Annotation of 43BSD/contrib/jove/re.c, revision 1.1.1.1

1.1       root        1: /*************************************************************************
                      2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
                      3:  * provided to you without charge for use only on a licensed Unix        *
                      4:  * system.  You may copy JOVE provided that this notice is included with *
                      5:  * the copy.  You may not sell copies of this program or versions        *
                      6:  * modified for use on microcomputer systems, unless the copies are      *
                      7:  * included with a Unix system distribution and the source is provided.  *
                      8:  *************************************************************************/
                      9: 
                     10: /* Search package. */
                     11: 
                     12: #include "jove.h"
                     13: #include "ctype.h"
                     14: 
                     15: #define NALTS  10      /* number of alternate search strings */
                     16: 
                     17: char   searchstr[128],
                     18:        compbuf[128],           /* global default compbuf */
                     19:        rep_search[128],        /* replace search string */
                     20:        rep_str[128],           /* contains replacement string */
                     21:        *cur_compb,             /* usually points at compbuf */
                     22:        REbuf[LBSIZE],          /* points at line we're scanning */
                     23:        *alternates[NALTS];
                     24: 
                     25: int    REdirection;
                     26: 
                     27: int    CaseIgnore = 0,
                     28:        WrapScan = 0,
                     29:        UseRE = 0;
                     30: 
                     31: #define cind_cmp(a, b) (Upper(a) == Upper(b))
                     32: 
                     33: private int    REpeekc;
                     34: private char   *REptr;
                     35: 
                     36: private
                     37: REgetc()
                     38: {
                     39:        int     c;
                     40: 
                     41:        if ((c = REpeekc) != -1)
                     42:                REpeekc = -1;
                     43:        else if (*REptr)
                     44:                c = *REptr++;
                     45:        else
                     46:                c = 0;
                     47: 
                     48:        return c;
                     49: }
                     50: 
                     51: #define STAR   01      /* Match any number of last RE. */
                     52: #define AT_BOL 2       /* ^ */
                     53: #define AT_EOL 4       /* $ */
                     54: #define AT_BOW 6       /* \< */
                     55: #define AT_EOW 8       /* \> */
                     56: #define OPENP  10      /* \( */
                     57: #define CLOSEP 12      /* \) */
                     58: #define CURLYB 14      /* \{ */
                     59: 
                     60: #define NOSTR  14      /* Codes <= NOSTR can't be *'d. */
                     61: 
                     62: #define ANYC   NOSTR+2         /* . */
                     63: #define NORMC  ANYC+2          /* normal character */
                     64: #define CINDC  NORMC+2         /* case independent character */
                     65: #define ONE_OF CINDC+2         /* [xxx] */
                     66: #define NONE_OF        ONE_OF+2        /* [^xxx] */
                     67: #define BACKREF        NONE_OF+2       /* \# */
                     68: #define EOP    BACKREF+2       /* end of pattern */
                     69: 
                     70: #define NPAR   9       /* [1-9] */
                     71: private int    nparens;
                     72: private char   *comp_p,
                     73:                **alt_p,
                     74:                **alt_endp;
                     75: 
                     76: REcompile(pattern, re, into_buf, alt_bufp)
                     77: char   *pattern,
                     78:        *into_buf,
                     79:        **alt_bufp;
                     80: {
                     81:        REptr = pattern;
                     82:        REpeekc = -1;
                     83:        comp_p = cur_compb = into_buf;
                     84:        alt_p = alt_bufp;
                     85:        alt_endp = alt_p + NALTS;
                     86:        *alt_p++ = comp_p;
                     87:        nparens = 0;
                     88:        (void) do_comp(re ? OKAY_RE : NORM);
                     89:        *alt_p = 0;
                     90: }
                     91: 
                     92: /* Compile the pattern into an internal code. */
                     93: 
                     94: private
                     95: do_comp(kind)
                     96: {
                     97:        char    *last_p;
                     98:        int     parens[NPAR],
                     99:                *parenp,
                    100:                c,
                    101:                ret_code;
                    102: 
                    103:        parenp = parens;
                    104:        last_p = 0;
                    105:        ret_code = 1;
                    106: 
                    107:        while (c = REgetc()) {
                    108:                if (comp_p > &cur_compb[(sizeof compbuf) - 4])
                    109:                        complain("Search string too long.");
                    110:                if (c != '*')
                    111:                        last_p = comp_p;
                    112:                if (kind == NORM && index(".[*", c) != 0)
                    113:                        goto defchar;
                    114:                switch (c) {
                    115:                case '\\':
                    116:                        switch (c = REgetc()) {
                    117:                        case 0:
                    118:                                complain("Premature end of pattern.");
                    119: 
                    120:                        case '{':
                    121:                            {
                    122:                                char    *wcntp;         /* Word count. */
                    123: 
                    124:                                *comp_p++ = CURLYB;
                    125:                                wcntp = comp_p;
                    126:                                *comp_p++ = 0;
                    127:                                for (;;) {
                    128:                                        int     comp_val;
                    129:                                        char    *comp_len;
                    130: 
                    131:                                        comp_len = comp_p++;
                    132:                                        comp_val = do_comp(IN_CB);
                    133:                                        *comp_len = comp_p - comp_len;
                    134:                                        (*wcntp)++;
                    135:                                        if (comp_val == 0)
                    136:                                                break;
                    137:                                }
                    138:                                continue;
                    139:                            }
                    140: 
                    141:                        case '}':
                    142:                                if (kind != IN_CB)
                    143:                                        complain("Unexpected \}.");
                    144:                                ret_code = 0;
                    145:                                goto outahere;
                    146: 
                    147:                        case '(':
                    148:                                if (nparens >= NPAR)
                    149:                                        complain("Too many ('s; max is %d.", NPAR);
                    150:                                *comp_p++ = OPENP;
                    151:                                *comp_p++ = nparens;
                    152:                                *parenp++ = nparens++;
                    153:                                continue;
                    154: 
                    155:                        case ')':
                    156:                                if (parenp == parens)
                    157:                                        complain("Too many )'s.");
                    158:                                *comp_p++ = CLOSEP;
                    159:                                *comp_p++ = *--parenp;
                    160:                                continue;
                    161: 
                    162:                        case '|':
                    163:                                if (alt_p >= alt_endp)
                    164:                                        complain("Too many alternates; max %d.", NALTS);
                    165:                                *comp_p++ = EOP;
                    166:                                *alt_p++ = comp_p;
                    167:                                continue;
                    168: 
                    169:                        case '1':
                    170:                        case '2':
                    171:                        case '3':
                    172:                        case '4':
                    173:                        case '5':
                    174:                        case '6':
                    175:                        case '7':
                    176:                        case '8':
                    177:                        case '9':
                    178:                                *comp_p++ = BACKREF;
                    179:                                *comp_p++ = c - '1';
                    180:                                continue;
                    181: 
                    182:                        case '<':
                    183:                                *comp_p++ = AT_BOW;
                    184:                                continue;
                    185: 
                    186:                        case '>':
                    187:                                *comp_p++ = AT_EOW;
                    188:                                continue;
                    189: 
                    190:                        default:
                    191:                                goto defchar;
                    192:                        }
                    193: 
                    194:                case ',':
                    195:                        if (kind != IN_CB)
                    196:                                goto defchar;
                    197:                        goto outahere;
                    198: 
                    199:                case '.':
                    200:                        *comp_p++ = ANYC;
                    201:                        continue;
                    202: 
                    203:                case '^':
                    204:                        if (comp_p == cur_compb || comp_p[-1] == EOP) {
                    205:                                *comp_p++ = AT_BOL;
                    206:                                continue;
                    207:                        }
                    208:                        goto defchar;
                    209: 
                    210:                case '$':
                    211:                        if ((REpeekc = REgetc()) != 0 && REpeekc != '\\')
                    212:                                goto defchar;
                    213:                        *comp_p++ = AT_EOL;
                    214:                        continue;
                    215: 
                    216:                case '[':
                    217:                    {
                    218:                        int     chrcnt;
                    219: 
                    220:                        *comp_p++ = ONE_OF;
                    221:                        bzero(comp_p, 16);
                    222:                        if ((REpeekc = REgetc()) == '^') {
                    223:                                *last_p = NONE_OF;
                    224:                                /* Get it for real this time. */
                    225:                                (void) REgetc();
                    226:                        }
                    227:                        chrcnt = 1;
                    228:                        while ((c = REgetc()) != ']' && c != 0) {
                    229:                                if (c == '\\')
                    230:                                        c = REgetc();
                    231:                                else if ((REpeekc = REgetc()) == '-') {
                    232:                                        int     c2;
                    233: 
                    234:                                        (void) REgetc();        /* read '-' */
                    235:                                        c2 = REgetc();
                    236:                                        while (c < c2) {
                    237:                                                comp_p[c/8] |= (1 << (c%8));
                    238:                                                c++;
                    239:                                        }
                    240:                                }
                    241:                                comp_p[c/8] |= (1 << (c%8));
                    242:                                chrcnt++;
                    243:                        }
                    244:                        if (c == 0)
                    245:                                complain("Missing ].");
                    246:                        if (chrcnt == 1)
                    247:                                complain("Empty [].");
                    248:                        comp_p += 16;
                    249:                        continue;
                    250:                    }
                    251: 
                    252:                case '*':
                    253:                        if (last_p == 0 || *last_p <= NOSTR)
                    254:                                goto defchar;
                    255:                        *last_p |= STAR;
                    256:                        continue;
                    257: 
                    258:                default:
                    259: defchar:               *comp_p++ = (CaseIgnore) ? CINDC : NORMC;
                    260:                        *comp_p++ = c;
                    261:                }
                    262:        }
                    263: outahere:
                    264:        /* End of pattern, let's do some error checking. */
                    265:        if (parenp != parens)
                    266:                complain("Unmatched ()'s.");
                    267:        if (kind == IN_CB && c == 0)    /* End of pattern with \}. */
                    268:                complain("Missing \}.");
                    269:        *comp_p++ = EOP;
                    270: 
                    271:        return ret_code;
                    272: }
                    273: 
                    274: private char   *pstrtlst[NPAR],        /* index into REbuf */
                    275:                *pendlst[NPAR],
                    276:                *REbolp,
                    277:                *locs,
                    278:                *loc1,
                    279:                *loc2;
                    280: 
                    281: int    REbom,
                    282:        REeom,          /* beginning and end of match */
                    283:        REalt_num;      /* if alternatives, which one matched? */
                    284: 
                    285: private
                    286: backref(n, linep)
                    287: register char  *linep;
                    288: {
                    289:        register char   *backsp,
                    290:                        *backep;
                    291: 
                    292:        backsp = pstrtlst[n];
                    293:        backep = pendlst[n];
                    294:        while (*backsp++ == *linep++)
                    295:                if (backsp >= backep)
                    296:                        return 1;
                    297:        return 0;
                    298: }
                    299: 
                    300: private
                    301: member(comp_p, c, af)
                    302: register char  *comp_p;
                    303: register int   c;
                    304: {
                    305:        register int    n;
                    306:        char    *base;
                    307: 
                    308:        if (c == 0)
                    309:                return 0;       /* try to match EOL always fails */
                    310:        if (comp_p[c/8] & (1 << (c%8)))
                    311:                return af;
                    312:        return !af;
                    313: }
                    314: 
                    315: private
                    316: REmatch(linep, comp_p)
                    317: register char  *linep,
                    318:                *comp_p;
                    319: {
                    320:        char    *first_p = linep;
                    321:        register int    n;
                    322: 
                    323:        for (;;) switch (*comp_p++) {
                    324:        case NORMC:
                    325:                if (*linep++ == *comp_p++)
                    326:                        continue;
                    327:                return 0;
                    328: 
                    329:        case CINDC:     /* case independent comparison */
                    330:                if (cind_cmp(*linep++, *comp_p++))
                    331:                        continue;
                    332:                return 0;
                    333: 
                    334:        case EOP:
                    335:                loc2 = linep;
                    336:                REeom = (loc2 - REbolp);
                    337:                return 1;       /* Success! */
                    338: 
                    339:        case AT_BOL:
                    340:                if (linep == REbolp)
                    341:                        continue;
                    342:                return 0;
                    343: 
                    344:        case AT_EOL:
                    345:                if (*linep == 0)
                    346:                        continue;
                    347:                return 0;
                    348: 
                    349:        case ANYC:
                    350:                if (*linep++ != 0)
                    351:                        continue;
                    352:                return 0;
                    353: 
                    354:        case AT_BOW:
                    355:                if (ismword(*linep) && (linep == REbolp || !ismword(linep[-1])))
                    356:                        continue;
                    357:                return 0;
                    358: 
                    359:        case AT_EOW:
                    360:                if ((*linep == 0 || !ismword(*linep)) &&
                    361:                    (linep != REbolp && ismword(linep[-1])))
                    362:                        continue;
                    363:                return 0;
                    364: 
                    365:        case ONE_OF:
                    366:        case NONE_OF:
                    367:                if (member(comp_p, *linep++, comp_p[-1] == ONE_OF)) {
                    368:                        comp_p += 16;
                    369:                        continue;
                    370:                }
                    371:                return 0;
                    372: 
                    373:        case OPENP:
                    374:                pstrtlst[*comp_p++] = linep;
                    375:                continue;
                    376: 
                    377:        case CLOSEP:
                    378:                pendlst[*comp_p++] = linep;
                    379:                continue;
                    380: 
                    381:        case BACKREF:
                    382:                if (pstrtlst[n = *comp_p++] == 0)
                    383:                        complain("\\%d was not specified.", n + 1);
                    384:                if (backref(n, linep)) {
                    385:                        linep += pendlst[n] - pstrtlst[n];
                    386:                        continue;
                    387:                }
                    388:                return 0;
                    389: 
                    390:        case CURLYB:
                    391:            {
                    392:                int     wcnt,
                    393:                        any;
                    394: 
                    395:                wcnt = *comp_p++;
                    396:                any = 0;
                    397: 
                    398:                while (--wcnt >= 0) {
                    399:                        if (any == 0)
                    400:                                any = REmatch(linep, comp_p + 1);
                    401:                        comp_p += *comp_p;
                    402:                }
                    403:                if (any == 0)
                    404:                        return 0;
                    405:                linep = loc2;
                    406:                continue;
                    407:            }
                    408: 
                    409:        case ANYC | STAR:
                    410:                first_p = linep;
                    411:                while (*linep++)
                    412:                        ;
                    413:                goto star;
                    414: 
                    415:        case NORMC | STAR:
                    416:                first_p = linep;
                    417:                while (*comp_p == *linep++)
                    418:                        ;
                    419:                comp_p++;
                    420:                goto star;
                    421: 
                    422:        case CINDC | STAR:
                    423:                first_p = linep;
                    424:                while (cind_cmp(*comp_p, *linep++))
                    425:                        ;
                    426:                comp_p++;
                    427:                goto star;
                    428: 
                    429:        case ONE_OF | STAR:
                    430:        case NONE_OF | STAR:
                    431:                first_p = linep;
                    432:                while (member(comp_p, *linep++, comp_p[-1] == (ONE_OF | STAR)))
                    433:                        ;
                    434:                comp_p += 16;
                    435:                goto star;
                    436: 
                    437:        case BACKREF | STAR:
                    438:                first_p = linep;
                    439:                n = *comp_p++;
                    440:                while (backref(n, linep))
                    441:                        linep += pendlst[n] - pstrtlst[n];
                    442:                while (linep >= first_p) {
                    443:                        if (REmatch(linep, comp_p))
                    444:                                return 1;
                    445:                        linep -= pendlst[n] - pstrtlst[n];
                    446:                }
                    447:                continue;
                    448: 
                    449: star:          do {
                    450:                        linep--;
                    451:                        if (linep < locs)
                    452:                                break;
                    453:                        if (REmatch(linep, comp_p))
                    454:                                return 1;
                    455:                } while (linep > first_p);
                    456:                return 0;
                    457: 
                    458:        default:
                    459:                complain("RE error match (%d).", comp_p[-1]);
                    460:        }
                    461:        /* NOTREACHED. */
                    462: }
                    463: 
                    464: private
                    465: REreset()
                    466: {
                    467:        register int    i;
                    468: 
                    469:        for (i = 0; i < NPAR; i++)
                    470:                pstrtlst[i] = pendlst[i] = 0;
                    471: }
                    472: 
                    473: /* Index LINE at OFFSET, the compiled EXPR, with alternates ALTS.  If
                    474:    lbuf_okay is nonzero it's okay to use linebuf if LINE is the current
                    475:    line.  This should save lots of time in things like paren matching in
                    476:    LISP mode.  Saves all that copying from linebuf to REbuf.  substitute()
                    477:    is the guy who calls re_lindex with lbuf_okay as 0, since the substitution
                    478:    gets placed in linebuf ... doesn't work too well when the source and
                    479:    destination strings are the same.  I hate all these arguments! */
                    480: 
                    481: re_lindex(line, offset, expr, alts, lbuf_okay)
                    482: Line   *line;
                    483: char   *expr,
                    484:        **alts;
                    485: {
                    486:        int     isquick;
                    487:        register int    firstc,
                    488:                        c;
                    489:        register char   *resp;
                    490: 
                    491:        REreset();
                    492:        if (lbuf_okay) {
                    493:                REbolp = lbptr(line);
                    494:                if (offset == -1)
                    495:                        offset = strlen(REbolp);        /* arg! */
                    496:        } else {
                    497:                REbolp = ltobuf(line, REbuf);
                    498:                if (offset == -1) {     /* Reverse search, find end of line. */
                    499:                        extern int      Jr_Len;
                    500: 
                    501:                        offset = Jr_Len;        /* Just Read Len. */
                    502:                }
                    503:        }
                    504:        resp = REbolp;
                    505:        isquick = (expr[0] == NORMC && alternates[1] == 0);
                    506:        if (isquick)
                    507:                firstc = expr[1];
                    508:        locs = REbolp + offset;
                    509: 
                    510:        if (REdirection == FORWARD) {
                    511:            do {
                    512:                char    **altp = alts;
                    513: 
                    514:                if (isquick) {
                    515:                        while ((c = *locs++) != 0 && c != firstc)
                    516:                                ;
                    517:                        if (*--locs == 0)
                    518:                                break;
                    519:                }
                    520:                REalt_num = 1;
                    521:                while (*altp) {
                    522:                        if (REmatch(locs, *altp++)) {
                    523:                                loc1 = locs;
                    524:                                REbom = loc1 - REbolp;
                    525:                                return 1;
                    526:                        }
                    527:                        REalt_num++;
                    528:                }
                    529:            } while (*locs++);
                    530:        } else {
                    531:            do {
                    532:                char    **altp = alts;
                    533: 
                    534:                if (isquick) {
                    535:                        while (locs >= REbolp && *locs-- != firstc)
                    536:                                ;
                    537:                        if (*++locs != firstc)
                    538:                                break;
                    539:                }
                    540:                REalt_num = 1;
                    541:                while (*altp) {
                    542:                        if (REmatch(locs, *altp++)) {
                    543:                                loc1 = locs;
                    544:                                REbom = loc1 - REbolp;
                    545:                                return 1;
                    546:                        }
                    547:                        REalt_num++;
                    548:                }
                    549:            } while (--locs >= resp);
                    550:        }
                    551: 
                    552:        return 0;
                    553: }
                    554: 
                    555: int    okay_wrap = 0;  /* Do a wrap search ... not when we're
                    556:                           parsing errors ... */
                    557: 
                    558: Bufpos *
                    559: dosearch(pattern, dir, re)
                    560: char   *pattern;
                    561: {
                    562:        Bufpos  *pos;
                    563: 
                    564:        if (bobp() && eobp())   /* Can't match!  There's no buffer. */
                    565:                return 0;
                    566: 
                    567:        REcompile(pattern, re, compbuf, alternates);
                    568: 
                    569:        okay_wrap++;
                    570:        pos = docompiled(dir, compbuf, alternates);
                    571:        okay_wrap = 0;
                    572:        return pos;
                    573: }
                    574: 
                    575: Bufpos *
                    576: docompiled(dir, expr, alts)
                    577: char   *expr,
                    578:        **alts;
                    579: {
                    580:        static Bufpos   ret;
                    581:        Bufpos  push_dot;
                    582:        register Line   *lp;
                    583:        register int    offset;
                    584:        int     we_wrapped = 0;
                    585: 
                    586:        lsave();
                    587:        /* Search now lsave()'s so it doesn't make any assumptions on
                    588:           whether the the contents of curline/curchar are in linebuf.
                    589:           Nowhere does search write all over linebuf.  However, we have to
                    590:           be careful about what calls we make here, because many of them
                    591:           assume (and rightly so) that curline is in linebuf. */
                    592: 
                    593:        REdirection = dir;
                    594:        DOTsave(&push_dot);
                    595:        if (dir == BACKWARD) {
                    596:                if (bobp()) {
                    597:                        if (okay_wrap && WrapScan) {
                    598:                                lp = curline;
                    599:                                goto doit;
                    600:                        }
                    601:                        return 0;
                    602:                }
                    603:                /* here we simulate BackChar() */
                    604:                if (bolp()) {
                    605:                        curline = curline->l_prev;
                    606:                        curchar = strlen(lbptr(curline));
                    607:                } else
                    608:                        --curchar;
                    609:        } else if (dir == FORWARD && (lbptr(curline)[curchar] == '\0') && !lastp(curline)) {
                    610:                curline = curline->l_next;
                    611:                curchar = 0;
                    612:        }
                    613:        lp = curline;
                    614:        offset = curchar;
                    615: 
                    616:        do {
                    617:                if (re_lindex(lp, offset, expr, alts, 1))
                    618:                        break;
                    619: doit:          lp = (dir == FORWARD) ? lp->l_next : lp->l_prev;
                    620:                if (lp == 0) {
                    621:                        if (okay_wrap && WrapScan) {
                    622:                                lp = (dir == FORWARD) ?
                    623:                                     curbuf->b_first : curbuf->b_last;
                    624:                                we_wrapped++;
                    625:                        } else
                    626:                                 break;
                    627:                }
                    628:                if (dir == FORWARD)
                    629:                        offset = 0;
                    630:                else
                    631:                        offset = -1;    /* Signals re_lindex ... */
                    632: 
                    633:        } while (lp != push_dot.p_line);
                    634: 
                    635:        if (lp == push_dot.p_line && we_wrapped)
                    636:                lp = 0;
                    637:        curline = push_dot.p_line;
                    638:        curchar = push_dot.p_char;
                    639:        if (lp == 0)
                    640:                return 0;
                    641:        ret.p_line = lp;
                    642:        ret.p_char = (dir == FORWARD) ? REeom : REbom;
                    643:        return &ret;
                    644: }
                    645: 
                    646: private char *
                    647: insert(off, endp, which)
                    648: char   *off,
                    649:        *endp;
                    650: {
                    651:        register char   *pp;
                    652:        register int    n;
                    653: 
                    654:        n = pendlst[which] - pstrtlst[which];
                    655:        pp = pstrtlst[which];
                    656:        while (--n >= 0) {
                    657:                *off++ = *pp++;
                    658:                if (off >= endp)
                    659:                        len_error(ERROR);
                    660:        }
                    661:        return off;
                    662: }
                    663: 
                    664: /* Perform the substitution.  If DELP is nonzero the matched string is
                    665:    deleted, i.e., the substitution string is not inserted. */
                    666: 
                    667: re_dosub(tobuf, delp)
                    668: char   *tobuf;
                    669: {
                    670:        register char   *tp,
                    671:                        *rp,
                    672:                        *repp;
                    673:        int     c;
                    674:        char    *endp;
                    675: 
                    676:        tp = tobuf;
                    677:        endp = tp + LBSIZE;
                    678:        rp = REbuf;
                    679:        repp = rep_str;
                    680: 
                    681:        while (rp < loc1)
                    682:                *tp++ = *rp++;
                    683: 
                    684:        if (!delp) while (c = *repp++) {
                    685:                if (c == '\\' && (c = *repp++) >= '1' && c <= nparens + '1') {
                    686:                        tp = insert(tp, endp, c - '1');
                    687:                        continue;
                    688:                }
                    689:                *tp++ = c;
                    690:                if (tp >= endp)
                    691:                        len_error(ERROR);
                    692:        }
                    693:        rp = loc2;
                    694:        loc2 = REbuf + max(1, tp - tobuf);
                    695:        REeom = loc2 - REbuf;
                    696:        /* At least one character past the match, to prevent an infinite
                    697:           number of replacements in the same position, e.g.,
                    698:           replace "^" with "". */
                    699:        while (*tp++ = *rp++)
                    700:                if (tp >= endp)
                    701:                        len_error(ERROR);
                    702: }
                    703: 
                    704: putmatch(which, buf, size)
                    705: char   *buf;
                    706: {
                    707:        *(insert(buf, buf + size, which - 1)) = 0;
                    708: }
                    709: 
                    710: setsearch(str)
                    711: char   *str;
                    712: {
                    713:        strcpy(searchstr, str);
                    714: }
                    715: 
                    716: char *
                    717: getsearch()
                    718: {
                    719:        return searchstr;
                    720: }
                    721: 
                    722: RErecur()
                    723: {
                    724:        char    sbuf[sizeof searchstr],
                    725:                cbuf[sizeof compbuf],
                    726:                repbuf[sizeof rep_str],
                    727:                *altbuf[NALTS];
                    728:        int     npars;
                    729:        Mark    *m = MakeMark(curline, REbom, FLOATER);
                    730: 
                    731:        message("Type C-X C-C to continue with query replace.");
                    732: 
                    733:        npars = nparens;
                    734:        byte_copy(compbuf, cbuf, sizeof compbuf);
                    735:        byte_copy(searchstr, sbuf, sizeof searchstr);
                    736:        byte_copy(rep_str, repbuf, sizeof rep_str);
                    737:        byte_copy((char *) alternates, (char *) altbuf, sizeof alternates);
                    738:        Recur();
                    739:        nparens = npars;
                    740:        byte_copy(cbuf, compbuf, sizeof compbuf);
                    741:        byte_copy(sbuf, searchstr, sizeof searchstr);
                    742:        byte_copy(repbuf, rep_str, sizeof rep_str);
                    743:        byte_copy((char *) altbuf, (char *) alternates, sizeof alternates);
                    744:        if (!exp_p)
                    745:                ToMark(m);
                    746:        DelMark(m);
                    747: }
                    748: 
                    749: ForSearch()
                    750: {
                    751:        search(FORWARD, UseRE);
                    752: }
                    753: 
                    754: RevSearch()
                    755: {
                    756:        search(BACKWARD, UseRE);
                    757: }
                    758: 
                    759: private
                    760: search(dir, re)
                    761: {
                    762:        Bufpos  *newdot;
                    763: 
                    764:        setsearch(ask(searchstr, ProcFmt));
                    765:        if ((newdot = dosearch(searchstr, dir, re)) == 0) {
                    766:                if (WrapScan)
                    767:                        complain("No \"%s\" in buffer.", searchstr);
                    768:                else
                    769:                        complain("No \"%s\" found to %s.", searchstr,
                    770:                                 (dir == FORWARD) ? "bottom" : "top");
                    771:        }
                    772:        PushPntp(newdot->p_line);
                    773:        SetDot(newdot);
                    774: }
                    775: 
                    776: /* Do we match PATTERN at OFFSET in BUF? */
                    777: 
                    778: LookingAt(pattern, buf, offset)
                    779: char   *pattern,
                    780:        *buf;
                    781: {
                    782:        register char   **alt = alternates;
                    783: 
                    784:        REcompile(pattern, 1, compbuf, alternates);
                    785:        REreset();
                    786:        locs = buf + offset;
                    787:        REbolp = buf;
                    788: 
                    789:        while (*alt)
                    790:                if (REmatch(locs, *alt++))
                    791:                        return 1;
                    792:        return 0;
                    793: }
                    794: 
                    795: look_at(expr)
                    796: char   *expr;
                    797: {
                    798:        REcompile(expr, 0, compbuf, alternates);
                    799:        REreset();
                    800:        locs = linebuf + curchar;
                    801:        REbolp = linebuf;
                    802:        if (REmatch(locs, alternates[0]))
                    803:                return 1;
                    804:        return 0;
                    805: }
                    806: 

unix.superglobalmegacorp.com

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