# 2.11BSD#431 - /usr/src/new/jove/re.c

##### Functions

    FSrchND           X
    ForSearch         X
    LookingAt         X
    REcompile         X
    REgetc            X
    REmatch           X
    RErecur           X
    REreset           X
    RSrchND           X
    RevSearch         X
    backref           X
    do_comp           X
    docompiled        X
    dosearch          X
    getsearch         X
    insert            X
    look_at           X
    member            X
    putmatch          X
    re_dosub          X
    re_lindex         X
    search            X
    setsearch         X

##### Variables

    CaseIgnore        X
    REalt_num         X
    REbolp            X
    REbom             X
    REbuf             X
    REdirection       X
    REeom             X
    REpeekc           X
    REptr             X
    alt_endp          X
    alt_p             X
    alternates        X
    comp_p            X
    compbuf           X
    cur_compb         X
    loc1              X
    loc2              X
    locs              X
    nparens           X
    okay_wrap         X
    pendlst           X
    private           X
    pstrtlst          X
    rep_search        X
    rep_str           X
    searchstr         X
    start_p           X

##### Macros

    ANYC              X
    AT_BOL            X
    AT_BOW            X
    AT_EOL            X
    AT_EOW            X
    BACKREF           X
    CINDC             X
    CLOSEP            X
    CURLYB            X
    EOP               X
    NALTS             X
    NONE_OF           X
    NORMC             X
    NOSTR             X
    NPAR              X
    ONE_OF            X
    OPENP             X
    STAR              X
    cind_cmp          X
    private           X

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

#### Defined functions

FSrchND defined in line 891; used 4 times

- in /usr/src/new/jove/externs.h line 288, 896
- in /usr/src/new/jove/funcdefs.c line 182, 519

ForSearch defined in line 879; used 4 times

- in /usr/src/new/jove/externs.h line 295, 903
- in /usr/src/new/jove/funcdefs.c line 181, 518

LookingAt defined in line 928; used 14 times

- in /usr/src/new/jove/extend.c line 125-126(2), 319, 1024
- in /usr/src/new/jove/externs.h line 57, 664
- in /usr/src/new/jove/insert.c line 750
- in /usr/src/new/jove/io.c line 566
- in /usr/src/new/jove/iproc.c line 212, 237-240(2)
- in /usr/src/new/jove/move.c line 219-221(2)
- in /usr/src/new/jove/re1.c line 288

REcompile defined in line 110; used 8 times

- in line 691, 935, 950
- in /usr/src/new/jove/c.c line 112
- in /usr/src/new/jove/externs.h line 352, 960
- in /usr/src/new/jove/proc.c line 128
- in /usr/src/new/jove/re1.c line 176

REgetc defined in line 69; used 12 times

- in line 27, 39, 150, 160, 263, 276-289(7)

REmatch defined in line 413; used 9 times

- in line 28, 40, 504, 547, 557, 639, 666, 941, 954

RErecur defined in line 851; used 3 times

- in /usr/src/new/jove/externs.h line 353, 961
- in /usr/src/new/jove/re1.c line 102

REreset defined in line 568; used 5 times

- in line 21, 33, 599, 936, 951

RSrchND defined in line 897; used 4 times

- in /usr/src/new/jove/externs.h line 354, 962
- in /usr/src/new/jove/funcdefs.c line 184, 521

RevSearch defined in line 885; used 4 times

- in /usr/src/new/jove/externs.h line 366, 974
- in /usr/src/new/jove/funcdefs.c line 183, 520

backref defined in line 385; used 4 times

- in line 24, 36, 488, 544

do_comp defined in line 129; used 4 times

- in line 25, 37, 123, 176

docompiled defined in line 697; used 5 times

- in line 693
- in /usr/src/new/jove/c.c line 125
- in /usr/src/new/jove/externs.h line 162, 770
- in /usr/src/new/jove/proc.c line 130

dosearch defined in line 682; used 13 times

- in line 913
- in /usr/src/new/jove/c.c line 311, 498-510(4)
- in /usr/src/new/jove/externs.h line 163, 771
- in /usr/src/new/jove/move.c line 189
- in /usr/src/new/jove/proc.c line 395
- in /usr/src/new/jove/re1.c line 333-334(2), 417

getsearch defined in line 845; used 3 times

- in /usr/src/new/jove/externs.h line 43, 650
- in /usr/src/new/jove/re1.c line 511

insert defined in line 763; used 5 times

- in line 18, 30, 809-813(2), 835

look_at defined in line 946; used 3 times

- in /usr/src/new/jove/externs.h line 99, 706
- in /usr/src/new/jove/re1.c line 413

member defined in line 400; used 4 times

- in line 26, 38, 469, 536

putmatch defined in line 831; used 10 times

- in /usr/src/new/jove/extend.c line 322, 328, 1026
- in /usr/src/new/jove/externs.h line 517, 1123
- in /usr/src/new/jove/io.c line 567
- in /usr/src/new/jove/proc.c line 132-133(2)
- in /usr/src/new/jove/re1.c line 292-293(2)

re_dosub defined in line 784; used 4 times

- in /usr/src/new/jove/externs.h line 522, 1128
- in /usr/src/new/jove/re1.c line 94, 137

re_lindex defined in line 588; used 4 times

- in line 737
- in /usr/src/new/jove/externs.h line 110, 717
- in /usr/src/new/jove/re1.c line 69

search defined in line 903; used 6 times

- in line 22, 34, 882, 888, 894, 900

setsearch defined in line 838; used 4 times

- in line 911
- in /usr/src/new/jove/externs.h line 536, 1142
- in /usr/src/new/jove/re1.c line 449

#### Defined variables

CaseIgnore defined in line 60; used 4 times

- in line 350
- in /usr/src/new/jove/re.c line 350
- in /usr/src/new/jove/re1.c line 389
- in /usr/src/new/jove/vars.c line 28

REalt_num defined in line 383; used 4 times

- in line 637, 644, 664, 671

REbolp defined in line 376; used 15 times

- in line 438-442(2), 457, 463, 601-605(3), 612, 620, 641, 653-658(2), 668, 938, 953

REbom defined in line 381; used 5 times

- in line 641, 668, 759, 859
- in /usr/src/new/jove/re1.c line 96

REbuf defined in line 55; used 4 times

- in line 605, 796, 821-822(2)

REdirection defined in line 58; used 3 times

- in line 622, 714
- in /usr/src/new/jove/re1.c line 64

REeom defined in line 382; used 6 times

- in line 438, 759, 822
- in /usr/src/new/jove/re1.c line 70-72(2), 140

REpeekc defined in line 66; used 7 times

- in line 74-75(2), 117, 263(2), 276, 285

REptr defined in line 67; used 3 times

- in line 76-77(2), 116

alt_endp defined in line 108; used 2 times

- in line 120, 207

alt_p defined in line 107; used 6 times

- in line 119-124(4), 207-212(2)

alternates defined in line 56; used 13 times

- in line 614, 691-693(2), 867(2), 873(2), 933-935(2), 950-954(2)
- in /usr/src/new/jove/re1.c line 69, 176

comp_p defined in line 105; used 80 times

- in line 118-121(2), 144-154(5), 168-177(5), 194-195(2), 202-203(2), 209-217(7), 229-238(4), 252-257(3), 265, 272-275(3), 291-295(2), 302, 334-341(6), 350-354(3), 362-363(2), 369, 401-402(2), 408, 414-432(7), 469-470(3), 476-484(3), 499-505(4), 521-530(4), 536-547(5), 557, 563

compbuf defined in line 51; used 13 times

- in line 151, 273, 691-693(2), 855, 864(2), 870(2), 935, 950
- in /usr/src/new/jove/re1.c line 69, 176

cur_compb defined in line 54; used 3 times

- in line 118, 151, 273

loc1 defined in line 378; used 5 times

- in line 640-641(2), 667-668(2), 799

loc2 defined in line 379; used 6 times

- in line 437-438(2), 509, 820-822(3)

locs defined in line 377; used 21 times

- in line 555, 620, 628-640(5), 646, 653-660(6), 666-667(2), 673, 937-941(2), 952-954(2)

nparens defined in line 104; used 12 times

- in line 122, 145-146(2), 192-196(3), 213-216(3), 808, 863, 869

okay_wrap defined in line 679; used 4 times

- in line 719, 741, 912-914(2)

pendlst defined in line 375; used 7 times

- in line 393, 480, 489, 545-549(2), 574, 771

private defined in line 903; never used
pstrtlst defined in line 374; used 9 times

- in line 392, 476, 484-489(2), 545-549(2), 574, 771-772(2)

rep_search defined in line 52; used 5 times

- in /usr/src/new/jove/re1.c line 175-180(5)

rep_str defined in line 53; used 8 times

- in line 797, 856, 866(2), 872(2)
- in /usr/src/new/jove/re1.c line 180-183(2)

searchstr defined in line 50; used 8 times

- in line 842, 848, 854, 865(2), 871(2), 909

start_p defined in line 106; used 4 times

- in line 118, 147, 217, 256

#### Defined macros

ANYC defined in line 95; used 3 times

- in line 96, 252, 513

AT_BOL defined in line 85; used 1 times

- in line 257

AT_BOW defined in line 87; used 1 times

- in line 234

AT_EOL defined in line 86; used 1 times

- in line 265

AT_EOW defined in line 88; used 1 times

- in line 238

BACKREF defined in line 100; used 3 times

- in line 101, 229, 541

CINDC defined in line 97; used 5 times

- in line 98, 350, 526, 613-617(2)

CLOSEP defined in line 90; used 3 times

- in line 202, 209, 362

CURLYB defined in line 91; used 1 times

- in line 168

EOP defined in line 101; used 2 times

- in line 211, 369

NALTS defined in line 48; used 4 times

- in line 56, 120, 208, 857

NONE_OF defined in line 99; used 3 times

- in line 100, 277, 534

NORMC defined in line 96; used 6 times

- in line 97, 350, 519, 613, 627, 652

NOSTR defined in line 93; used 2 times

- in line 95, 307

NPAR defined in line 103; used 6 times

- in line 134, 192-193(2), 374-375(2), 573

ONE_OF defined in line 98; used 5 times

- in line 99, 272, 469, 533-536(2)

OPENP defined in line 89; used 3 times

- in line 144, 194, 214

STAR defined in line 84; used 4 times

- in line 335-344(3), 536

cind_cmp defined in line 64; used 2 times

- in line 432, 528

private defined in line 45; used 18 times

- in line 13-23(4), 30-35(3), 44, 66-69(3), 105, 129, 385, 400, 413, 568, 763

Last modified: 1988-12-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2101 |