|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.