Annotation of researchv9/cmd/emacs/emacs_re.c, revision 1.1.1.1

1.1       root        1: #include "emacs_gb.h"
                      2: #include "emacs_io.h"
                      3: 
                      4: 
                      5: /* EMACS_MODES: c !fill */
                      6: 
                      7: #define GETC() (*sp++)
                      8: #define PEEKC() (*sp)
                      9: #define UNGETC(c) (--sp)
                     10: #define RETURN(c) return(NULL);
                     11: #define ERROR(c) return(c);
                     12: 
                     13: extern char casem[];
                     14: extern char bits[];
                     15: 
                     16: #define RESIZE 256
                     17: 
                     18: /* basic comparison types */
                     19: 
                     20: #define CCHR 1                         /* single char */
                     21: #define CDOT 2                         /* any char */
                     22: #define CCL 3                          /* multiple guess */
                     23: #define CBLST 4                                /* last expression */
                     24: #define CDOL 5                         /* $ */
                     25: #define CEOF 6                         /* end of line */
                     26: 
                     27: /* markers */
                     28: 
                     29: #define CBRA 8                         /* \( marker */
                     30: #define CKET 9                         /* \) marker */
                     31: #define CBWD 10                                /* start of word */
                     32: #define CEWD 11                                /* end of word */
                     33: 
                     34: /* modifiers */
                     35: 
                     36: #define BASTYP 15                      /* mask for base type */
                     37: 
                     38: #define RNGE 16                                /* range of types */
                     39: 
                     40: #define        NBRA    9
                     41: 
                     42: #define PLACE(c)       ep[c >> 3] ^= bittab[c & 07]
                     43: #define ISTHERE(c)     (ep[c >> 3] & bittab[c & 07])
                     44: 
                     45: char   *braslist[NBRA];
                     46: char   *braelist[NBRA];
                     47: int    nbra, ebra;
                     48: char   *loc1;
                     49: int closed;
                     50: int    loc2;
                     51: 
                     52: int    low;
                     53: int    size;
                     54: 
                     55: char   bittab[] = {
                     56:        1,
                     57:        2,
                     58:        4,
                     59:        8,
                     60:        16,
                     61:        32,
                     62:        64,
                     63:        128
                     64: };
                     65: 
                     66: int
                     67: compile(sp, ep)
                     68: register char *ep;
                     69: register char *sp;
                     70: 
                     71: /* Keywords: regular-expressions searching parsing */
                     72: {
                     73:        register int c;
                     74:        char *endbuf;
                     75:        char *lastep = sp;
                     76:        char bracket[NBRA], *bracketp;
                     77:        char neg;
                     78:        int lc;
                     79:        int i, cflg;
                     80: 
                     81:        lastep = NULL;
                     82:        bracketp = bracket;
                     83:        closed = nbra = ebra = 0;
                     84: 
                     85:        endbuf = ep + RESIZE;
                     86: 
                     87:        for (;;) {
                     88:                if (ep >= endbuf)
                     89:                        ERROR(62);
                     90:                if((c = GETC()) != '*' && (c != '+') &&
                     91:                        ((c != '\\') || (PEEKC() != '{')))
                     92:                        lastep = ep;
                     93:                if (c == 0) {
                     94:                        *ep++ = CEOF;
                     95:                        RETURN(ep);
                     96:                }
                     97:                switch (c) {
                     98: 
                     99:                case '.':
                    100:                        *ep++ = CDOT;
                    101:                        continue;
                    102: 
                    103:                case '\n':
                    104:                        ERROR(55);
                    105:                case '*':
                    106:                        if (lastep==0 || *lastep==CBRA || *lastep==CKET)
                    107:                                goto defchar;
                    108:                        *lastep |= RNGE;
                    109:                        *ep++=0;
                    110:                        *ep++=255;
                    111:                        continue;
                    112:                case '+':
                    113:                        if (lastep==0 ) 
                    114:                                goto defchar;
                    115:                        *lastep |= RNGE;
                    116:                        *ep++ = 1;
                    117:                        *ep++ = 255;
                    118:                        continue;
                    119: 
                    120:                case '$':
                    121:                        if(PEEKC() != 0)
                    122:                                goto defchar;
                    123:                        *ep++ = CDOL;
                    124:                        continue;
                    125: 
                    126:                case '[':
                    127:                        if(&ep[17] >= endbuf)
                    128:                                ERROR(62);
                    129: 
                    130:                        *ep++ = CCL;
                    131:                        lc = 0;
                    132:                        if((c = GETC()) == '^') {
                    133:                                neg = -1;
                    134:                                c = GETC();
                    135:                        } else neg = 0;
                    136:                        for(i = 0; i < 16; i++)
                    137:                                ep[i] = neg;
                    138: 
                    139: 
                    140:                        do {
                    141:                                if(c == '\0')
                    142:                                        ERROR(61);
                    143:                                if(c == '-' && (lc != 0) && (PEEKC() != ']')) {
                    144:                                        c = GETC();
                    145:                                } else lc = c;
                    146:                                while(lc <= c) {
                    147:                                        PLACE(lc);
                    148:                                        lc++;
                    149:                                }
                    150:                        } while((c = GETC()) != ']');
                    151:                        ep[1] &= 0373; /* make sure that newline is not matched */
                    152:                        ep += 16;                       
                    153:                        continue;
                    154: 
                    155:                case '\\':
                    156:                        switch(c = GETC()) {
                    157: 
                    158:                        case '(':
                    159:                                if(nbra >= NBRA)
                    160:                                        ERROR(57);
                    161:                                *bracketp++ = nbra;
                    162:                                *ep++ = CBRA;
                    163:                                *ep++ = nbra++;
                    164:                                continue;
                    165: 
                    166:                        case ')':
                    167:                                if(bracketp <= bracket || ++ebra != nbra)
                    168:                                        ERROR(56);
                    169:                                *ep++ = CKET;
                    170:                                *ep++ = *--bracketp;
                    171:                                closed++;
                    172:                                continue;
                    173: 
                    174:                        case '<':
                    175:                                *ep++ = CBWD;
                    176:                                continue;
                    177:                        case '>':
                    178:                                *ep++ = CEWD;
                    179:                                continue;
                    180:                                
                    181:                        case '{':
                    182:                                if(lastep == (char *) (0))
                    183:                                        goto defchar;
                    184:                                *lastep |= RNGE;
                    185:                                cflg = 0;
                    186:                        nlim:
                    187:                                c = GETC();
                    188:                                if (c == '\\') {
                    189:                                        i = 255; /* infinity */
                    190:                                } else {
                    191:                                        i = 0;
                    192:                                        while('0' <= c && c <= '9') {
                    193:                                                i = 10 * i + (c - '0');
                    194:                                                c = GETC();
                    195:                                        }
                    196:                                }
                    197:                                if (i > 255) ERROR(52);
                    198:                                *ep++ = i;
                    199:                                if (c == ',') {
                    200:                                        if(cflg++) ERROR(58);
                    201:                                        goto nlim; /* get 2'nd number */
                    202:                                }
                    203:                                if((c != '\\') || (GETC() != '}')) ERROR(59);
                    204:                                if(!cflg)       /* one number */
                    205:                                        *ep++ = i;
                    206:                                else if((ep[-1] & 0377) < (ep[-2] & 0377))
                    207:                                        ERROR(60);
                    208:                                continue;
                    209: 
                    210:                        case '\n':
                    211:                                ERROR(55);
                    212: 
                    213:                        case 'n':
                    214:                                c = '\n';
                    215:                                goto defchar;
                    216: 
                    217:                        default:
                    218:                                if(c >= '1' && c <= '9') {
                    219:                                        if((c -= '1') >= closed)
                    220:                                                ERROR(54);
                    221:                                        *ep++ = CBLST;
                    222:                                        *ep++ = c;
                    223:                                        continue;
                    224:                                }
                    225:                        }
                    226:                        /* Drop through to default to use \ to turn off special chars */
                    227: 
                    228:                defchar:
                    229:                default:
                    230:                        lastep = ep;
                    231:                        *ep++ = CCHR;
                    232:                        *ep++ = c;
                    233:                }
                    234:        }
                    235: }
                    236: 
                    237: 
                    238: advance(lp, ep)
                    239: register char *lp, *ep;
                    240: 
                    241: /* Keywords: regular-expressions searching star-processing:10 */
                    242: 
                    243: {
                    244:        register char *curlp;
                    245:        char c;
                    246:        int typ;
                    247:        char *bbeg;
                    248:        int ct;
                    249: 
                    250:        for (;;) switch (typ = *ep++) {
                    251: 
                    252:        case CCHR:
                    253:                if (*ep++ == casem[(*lp++)&0177])
                    254:                        continue;
                    255:                return(0);
                    256: 
                    257:        case CDOT:
                    258:                if (*lp++ != EOL)
                    259:                        continue;
                    260:                return(0);
                    261: 
                    262:        case CBWD:
                    263:                if (bits[lp[-1]] & 01) continue;
                    264:                return(0);
                    265:        case CEWD:
                    266:                if (bits[*lp] & 01) continue;
                    267:                return(0);
                    268:        case CDOL:
                    269:                if (*lp==EOL) {
                    270:                        continue;
                    271:                }
                    272:                return(0);
                    273: 
                    274:        case CEOF:
                    275:                loc2 = lp-klptr;
                    276:                return(1);
                    277: 
                    278:        case CCL:
                    279:                c = casem[*lp++ & 0177];
                    280:                if(ISTHERE(c)) {
                    281:                        ep += 16;
                    282:                        continue;
                    283:                }
                    284:                return(0);
                    285:        case CBRA:
                    286:                braslist[*ep++] = lp;
                    287:                continue;
                    288: 
                    289:        case CKET:
                    290:                braelist[*ep++] = lp;
                    291:                continue;
                    292: 
                    293:        case CCHR|RNGE:
                    294:                c = *ep++;
                    295:                getrnge(ep);
                    296: grnge:         ct = 0;
                    297:                curlp = lp;
                    298:                while(ct < size) {
                    299:                        switch(typ&BASTYP) {
                    300:                                
                    301:                        case CCHR: if(casem[(*lp++)&0177] != c) goto broke;
                    302:                                break;
                    303:                        case CDOT: if (*lp++ == EOL) goto broke;
                    304:                                break;
                    305:                        case CCL: c = casem[(*lp++)&0177];
                    306:                                if(!ISTHERE(c)) goto broke;
                    307:                                break;
                    308:                        }
                    309:                        if (++ct == low) curlp = lp;
                    310:                }
                    311: broke:         if (ct < low) return(0); /* too few */
                    312: 
                    313:                if (size == ct) lp++;   /* didn't do last compare */
                    314:                if ((typ&BASTYP) == CCL) ep += 16;
                    315:                ep += 2;
                    316: 
                    317:                while (lp > curlp) {
                    318:                        if (advance(--lp, ep)) return(1);
                    319:                }
                    320:                return(0);
                    321:        case CDOT|RNGE:
                    322:                getrnge(ep);
                    323:                goto grnge;
                    324:        case CCL|RNGE:
                    325:                getrnge(ep + 16);
                    326:                goto grnge;
                    327:        case CBLST:
                    328:                bbeg = braslist[*ep];
                    329:                ct = braelist[*ep++] - bbeg;
                    330: 
                    331:                if(ecmp(bbeg, lp, ct)) {
                    332:                        lp += ct;
                    333:                        continue;
                    334:                }
                    335:                return(0);
                    336: 
                    337:        case CBLST|RNGE:
                    338:                bbeg = braslist[*ep];
                    339:                ct = braelist[*ep++] - bbeg;
                    340:                ep+=2;
                    341:                curlp = lp;
                    342:                while(ecmp(bbeg, lp, ct))
                    343:                        lp += ct;
                    344: 
                    345:                while(lp >= curlp) {
                    346:                        if(advance(lp, ep))     return(1);
                    347:                        lp -= ct;
                    348:                }
                    349:                return(0);
                    350:        }
                    351: }
                    352: 
                    353: getrnge(str)
                    354: register char *str;
                    355: /* Keywords: regular-expressions searching:20 star-processing */
                    356: 
                    357: {
                    358:        low = *str++ & 0377;
                    359:        size = *str&0377;
                    360:        if (size == 255) size = 2000;
                    361: }
                    362: 
                    363: ecmp(a, b, count)
                    364: register char  *a, *b;
                    365: register int count;
                    366: 
                    367: /* Keywords: star-processing regular-expressions searching:10 */
                    368: 
                    369: {
                    370:        while(count--)
                    371:                if(*a++ != *b++)        return(0);
                    372:        return(1);
                    373: }
                    374: 
                    375: 
                    376: 
                    377: rsrch(arg)
                    378: 
                    379: /* Keywords: searching regular-expressions commands key-bindings:10 */
                    380: 
                    381: int arg;
                    382: {
                    383:        register int dir;
                    384:        extern char presst[];
                    385:        register char *xp;
                    386:        register char c;
                    387:        int ol,oc;
                    388:        int x,y;        
                    389:        
                    390:        if (arg < 0) {
                    391:                dir = -1;
                    392:                arg = -arg;
                    393:        } else {
                    394:                dir = 1;
                    395:        }
                    396:        ol = curln;
                    397:        oc = column;
                    398:        if (xp = getname("expr: ")) {   /* get expression */
                    399:                if (*xp == 0) xp = presst; /* last string */
                    400:                prompt1("expr: %s",xp);
                    401:                while(rgsrch(curln,column,xp,(arg == 1),dir)) {
                    402:                        move(kline,kcol);
                    403:                        ol = curln;
                    404:                        oc = column;
                    405:                        strcpy(presst,xp);
                    406:                        if (infrn == 0) {
                    407:                                disup();
                    408:                                x = mline;
                    409:                                y = mcol;
                    410:                                prompt1("expr: %s",xp);
                    411:                                mgo(x,y);
                    412:                                c = getchar();
                    413:                        } else return(1);
                    414:                        
                    415:                        if (x=issrch(c)) {
                    416:                                dir=x;
                    417:                                forw(dir);
                    418:                        } else {
                    419:                                unprompt();
                    420:                                ungetch(c);
                    421:                                return(1);
                    422:                        }
                    423:                }
                    424:                prompt1("Search failed");
                    425:                move(ol,oc);
                    426:                if (infrn >=0) beep();
                    427:        }
                    428:        return(0);
                    429: }
                    430: 
                    431: /* rgsrch -- regular expression search */
                    432: 
                    433: rgsrch(froml,fromc,cp,wrap,dir)
                    434: int froml;
                    435: int fromc;
                    436: int wrap;
                    437: register int dir;
                    438: char *cp;
                    439: 
                    440: /* Keywords: regular-expressions searching query-replace:20 */
                    441: 
                    442: {
                    443:        register int en;
                    444:        char rebuf[RESIZE];
                    445:        register int beg;
                    446:        char *lp;
                    447:        
                    448:        lp = cp;
                    449:        while (beg = *lp) *lp++ = casem[beg&0177]; /* map string to allowed case */
                    450:        if (*cp == '^') {
                    451:                cp++;
                    452:                beg = 1;
                    453:        } else beg = 0;
                    454:        if (en = compile(cp,rebuf)) { /* if format error */
                    455:                error(WARN,en);
                    456:                return(0);
                    457:        }
                    458:        kline = froml;
                    459:        kcol = fromc;
                    460: 
                    461:        while (1) {
                    462:                if (brkflg) brkit();
                    463:                klptr = mkline(kline);
                    464:                if (beg) {
                    465:                        if ((kcol == 0) || (dir<0)) {
                    466:                                kcol = 0;
                    467:                                if(advance(klptr,rebuf)) {
                    468:                                        loc1 = klptr+kcol;
                    469:                                        return(1);
                    470:                                }
                    471:                        }
                    472:                } else { 
                    473:                        while (1) {
                    474:                                if ((rebuf[0] != CCHR) || (rebuf[1] == casem[klptr[kcol]&0177])) {
                    475: 
                    476:                                        if (advance(klptr+kcol, rebuf)) {
                    477: 
                    478: /* The following line rejects an attempt to match the last newline in the buffer */
                    479:                                                if ((kline == nlines) && klptr[kcol] == EOL) goto nomatch;
                    480:                                                loc1 = klptr+kcol;
                    481:                                                return(1);
                    482:                                        }
                    483:                                }
                    484:                                if (dir>0) {
                    485:                                        if (klptr[kcol] == EOL) goto nomatch;
                    486:                                        else kcol++;
                    487:                                } else {
                    488:                                        if (kcol == 0) goto nomatch;
                    489:                                        else kcol--;
                    490:                                }
                    491:                                if ((kline == froml) && (kcol == fromc)) return(0);
                    492:                        }
                    493:                }
                    494: nomatch:       kline += dir;
                    495:                if (wrap) {
                    496:                        if (kline > nlines) kline = 1;
                    497:                        if (kline < 1) kline = nlines;
                    498: 
                    499:                } else {
                    500:                        if ((kline > nlines) || (kline <1)) return(0);
                    501:                }
                    502:                if (beg || (dir>0))  kcol = 0;
                    503:                else kcol = leng(kline);
                    504:                if (wrap && (kline == froml) && (kcol == fromc)) return(0);
                    505:                if (beg && (kline == froml)) return(0);
                    506:        }
                    507: }                      
                    508: 
                    509: /* regrep -- replace sub expression */
                    510: /* assumes last deleted text is in the kill stack, pointers set up */
                    511: 
                    512: regrep(i)
                    513: 
                    514: register int i;
                    515: 
                    516: /* Keywords: query-replace commands regular-expressions */
                    517: 
                    518: 
                    519: {
                    520:        register int x;
                    521:        register int y;
                    522:        
                    523:        if (i <= closed) {
                    524:                yank(1);                /* bring back everything */
                    525:                y = braslist[i]-loc1;   /* length to kill */            
                    526:                back(y);        /* adjust mark position correctly */
                    527:                
                    528:                exch(1);                /* back to beggining */
                    529:                fdel(y);                 /* kill first part */
                    530:                kpop();
                    531:                forw(braelist[i]-braslist[i]);
                    532:                mkill(1);               /* now kill the rest */
                    533:                kpop();
                    534:                unpop(3);               /* Remove from the undo stack */
                    535:                return(1);
                    536:        } else return(0);
                    537: }

unix.superglobalmegacorp.com

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