|
|
1.1 ! root 1: /* ! 2: * A stream editor. ! 3: * Execution. ! 4: */ ! 5: #include <stdio.h> ! 6: #include <ctype.h> ! 7: #include "sed.h" ! 8: ! 9: char *match(); ! 10: ! 11: /* ! 12: * Execute the compiled commands on each line of the input file. ! 13: */ ! 14: process() ! 15: { ! 16: FILE *fp; ! 17: QCL **qcrpp, *qcrp, *lqp, *qp; ! 18: int n, subflag; ! 19: char com; ! 20: register COM *cp; ! 21: register char *bp1, *bp2; ! 22: ! 23: subflag = 0; ! 24: cp = NULL; ! 25: com = '\0'; ! 26: lno = 0; ! 27: qcrpp = &qcrp; ! 28: dolflag = 0; ! 29: pattlen = 0; ! 30: holdlen = 0; ! 31: pattbuf[0] = '\0'; ! 32: holdbuf[0] = '\0'; ! 33: for (;;) { ! 34: while (cp == NULL) { ! 35: if (com != 'D') { ! 36: if (nflag==0 && pattlen!=0) ! 37: printf("%s\n", pattbuf); ! 38: pattlen = 0; ! 39: } ! 40: *qcrpp = NULL; ! 41: qp = qcrp; ! 42: while (qp != NULL) { ! 43: cp = qp->q_comp; ! 44: lqp = qp; ! 45: qp = qp->q_next; ! 46: free(lqp); ! 47: switch (cp->c_name) { ! 48: case 'a': ! 49: printf("%s\n", cp->c_p.p_buf); ! 50: break; ! 51: case 'r': ! 52: bp1 = cp->c_p.p_buf; ! 53: if ((fp=fopen(bp1, "r")) == NULL) { ! 54: printe("Cannot open %s", bp1); ! 55: continue; ! 56: } ! 57: while (fgets(linebuf, LHPSIZE, fp)) ! 58: printf("%s", linebuf); ! 59: fclose(fp); ! 60: } ! 61: } ! 62: if (com == 'q') ! 63: exit(0); ! 64: if (com != 'D') { ! 65: if (readpat() == 0) ! 66: exit(0); ! 67: } ! 68: cp = comp; ! 69: qcrpp = &qcrp; ! 70: com = '\0'; ! 71: } ! 72: if (admitr(cp) == 0) { ! 73: cp = cp->c_next; ! 74: continue; ! 75: } ! 76: switch (com=cp->c_name) { ! 77: case '=': ! 78: printf("%d\n", lno); ! 79: break; ! 80: case '{': ! 81: cp = cp->c_p.p_com; ! 82: continue; ! 83: case '}': ! 84: break; ! 85: case 'a': ! 86: *qcrpp = qp = (QCL *)salloc(sizeof (QCL)); ! 87: qp->q_comp = cp; ! 88: qcrpp = &qp->q_next; ! 89: break; ! 90: case 'b': ! 91: cp = cp->c_p.p_lab->l_comp; ! 92: continue; ! 93: case 'c': ! 94: if (cp->c_iran == 0) ! 95: printf("%s\n", cp->c_p.p_buf); ! 96: case 'd': ! 97: pattlen = 0; ! 98: cp = NULL; ! 99: continue; ! 100: case 'D': ! 101: bp1 = bp2 = pattbuf; ! 102: pattlen = 0; ! 103: while (*bp2 != '\0') { ! 104: if (*bp2++ == '\n') { ! 105: pattlen = 1; ! 106: break; ! 107: } ! 108: } ! 109: while (*bp1++=*bp2++) ! 110: pattlen++; ! 111: if (pattlen == 0) ! 112: com = 'd'; ! 113: cp = NULL; ! 114: continue; ! 115: case 'g': ! 116: n = pattlen = holdlen; ! 117: bp1 = pattbuf; ! 118: bp2 = holdbuf; ! 119: while (n--) ! 120: *bp1++ = *bp2++; ! 121: break; ! 122: case 'G': ! 123: if (pattlen+holdlen > LHPSIZE) { ! 124: printe("Pattern buffer overflow"); ! 125: break; ! 126: } ! 127: bp1 = &pattbuf[pattlen]; ! 128: bp2 = &holdbuf[0]; ! 129: if (pattlen != 0) ! 130: bp1[-1] = '\n'; ! 131: pattlen += n = holdlen; ! 132: while (n--) ! 133: *bp1++ = *bp2++; ! 134: break; ! 135: case 'h': ! 136: n = holdlen = pattlen; ! 137: bp1 = holdbuf; ! 138: bp2 = pattbuf; ! 139: while (n--) ! 140: *bp1++ = *bp2++; ! 141: break; ! 142: case 'H': ! 143: if (holdlen+pattlen > LHPSIZE) { ! 144: printe("Hold buffer overflow"); ! 145: break; ! 146: } ! 147: bp1 = &holdbuf[holdlen]; ! 148: bp2 = &pattbuf[0]; ! 149: if (holdlen != 0) ! 150: bp1[-1] = '\n'; ! 151: holdlen += n = pattlen; ! 152: while (n--) ! 153: *bp1++ = *bp2++; ! 154: break; ! 155: case 'i': ! 156: printf("%s\n", cp->c_p.p_buf); ! 157: break; ! 158: case 'l': ! 159: execlis(); ! 160: break; ! 161: case 'n': ! 162: if (pattlen != 0) ! 163: printf("%s\n", pattbuf); ! 164: pattlen = 0; ! 165: case 'N': ! 166: if (readpat() == 0) { ! 167: com = 'q'; ! 168: cp = NULL; ! 169: continue; ! 170: } ! 171: break; ! 172: case 'p': ! 173: if (pattlen != 0) ! 174: printf("%s\n", pattbuf); ! 175: break; ! 176: case 'P': ! 177: bp1 = pattbuf; ! 178: while (*bp1!='\0' && *bp1!='\n') ! 179: putchar(*bp1++); ! 180: putchar('\n'); ! 181: break; ! 182: case 'q': ! 183: cp = NULL; ! 184: continue; ! 185: case 'r': ! 186: *qcrpp = qp = (QCL *)salloc(sizeof (QCL)); ! 187: qp->q_comp = cp; ! 188: qcrpp = &qp->q_next; ! 189: break; ! 190: case 's': ! 191: subflag = execsub(cp->c_p.p_sub); ! 192: break; ! 193: case 't': ! 194: if (subflag) { ! 195: cp = cp->c_p.p_lab->l_comp; ! 196: continue; ! 197: } ! 198: break; ! 199: case 'w': ! 200: fprintf(cp->c_p.p_fil->f_filp, "%s\n", pattbuf); ! 201: break; ! 202: case 'x': ! 203: n = pattlen; ! 204: bp1 = linebuf; ! 205: bp2 = pattbuf; ! 206: while (n--) ! 207: *bp1++ = *bp2++; ! 208: n = holdlen; ! 209: bp1 = pattbuf; ! 210: bp2 = holdbuf; ! 211: while (n--) ! 212: *bp1++ = *bp2++; ! 213: n = pattlen; ! 214: bp1 = holdbuf; ! 215: bp2 = linebuf; ! 216: while (n--) ! 217: *bp1++ = *bp2++; ! 218: n = pattlen; ! 219: pattlen = holdlen; ! 220: holdlen = n; ! 221: break; ! 222: case 'y': ! 223: bp2 = cp->c_p.p_buf; ! 224: for (bp1=pattbuf; *bp1; bp1++) ! 225: *bp1 = bp2[*bp1]; ! 226: break; ! 227: } ! 228: cp = cp->c_next; ! 229: } ! 230: } ! 231: ! 232: /* ! 233: * See if a the current line is within a given line range. ! 234: */ ! 235: admitr(cp) ! 236: register COM *cp; ! 237: { ! 238: register int n; ! 239: ! 240: switch (cp->c_nadd) { ! 241: case 0: ! 242: cp->c_iran = 0; ! 243: n = 1; ! 244: break; ! 245: case 1: ! 246: cp->c_iran = 0; ! 247: n = admits(&cp->c_a[0]); ! 248: break; ! 249: case 2: ! 250: if (cp->c_iran == 0) { ! 251: n = cp->c_iran = admits(&cp->c_a[0]); ! 252: } else { ! 253: if (admits(&cp->c_a[1]) != 0) ! 254: cp->c_iran = 0; ! 255: n = 1; ! 256: } ! 257: } ! 258: return (cp->c_notf!=n); ! 259: } ! 260: ! 261: /* ! 262: * See if the current line matches the given line address. ! 263: */ ! 264: admits(ap) ! 265: register ADD *ap; ! 266: { ! 267: if (ap->a_lno == 0) ! 268: return (execute(ap->a_pat)); ! 269: if (ap->a_lno == HUGE) ! 270: return (dolflag); ! 271: return (ap->a_lno-1 == lno); ! 272: } ! 273: ! 274: /* ! 275: * Append a line into the pattern buffer. The current line number ! 276: * is incremented. If the line overflows, an error message is ! 277: * printed out. ! 278: */ ! 279: readpat() ! 280: { ! 281: static int lastc = '\0'; ! 282: register int c, n; ! 283: register char *cp; ! 284: ! 285: if (dolflag) ! 286: return (0); ! 287: cp = &pattbuf[pattlen]; ! 288: if (pattlen != 0) ! 289: cp[-1] = '\n'; ! 290: n = &pattbuf[LHPSIZE-1] - cp; ! 291: if (lastc == '\0') ! 292: c = getp(); ! 293: else { ! 294: c = lastc; ! 295: lastc = '\0'; ! 296: } ! 297: while (c!='\n' && c!=EOF) { ! 298: if (n-- <= 0) { ! 299: fprintf(stderr, "%d: Line too long\n", lno); ! 300: exit(1); ! 301: } ! 302: *cp++ = c; ! 303: c = getp(); ! 304: } ! 305: *cp++ = '\0'; ! 306: pattlen = cp - pattbuf; ! 307: lno++; ! 308: if (c==EOF || (c=getp())==EOF) ! 309: dolflag++; ! 310: else ! 311: lastc = c; ! 312: return (1); ! 313: } ! 314: ! 315: /* ! 316: * Get a character. ! 317: */ ! 318: getp() ! 319: { ! 320: ECL *ep; ! 321: register int c; ! 322: ! 323: while (ifp==NULL || (c=getc(ifp))==EOF) { ! 324: if (ifp != NULL) ! 325: fclose(ifp); ! 326: if ((ep=eclp) == NULL) ! 327: return (EOF); ! 328: if ((ifp=fopen(ep->e_argp, "r")) == NULL) { ! 329: fprintf(stderr, "Cannot open %s\n", ep->e_argp); ! 330: exit(1); ! 331: } ! 332: eclp = ep->e_next; ! 333: free(ep); ! 334: } ! 335: return (c); ! 336: } ! 337: ! 338: /* ! 339: * Print out the contents of the pattern buffer in an unambigous ! 340: * form. All non-printing characters are escaped. ! 341: */ ! 342: execlis() ! 343: { ! 344: register int n; ! 345: register char *cp; ! 346: ! 347: n = 0; ! 348: for (cp=pattbuf; *cp; cp++) { ! 349: if (n++ >= 72) { ! 350: n = 0; ! 351: printf("\\\n"); ! 352: } ! 353: switch (*cp) { ! 354: case '\b': ! 355: printf("-\b<"); ! 356: continue; ! 357: case '\t': ! 358: printf("-\b>"); ! 359: continue; ! 360: case '\\': ! 361: printf("\\\\"); ! 362: continue; ! 363: default: ! 364: if (isascii(*cp) && !iscntrl(*cp)) { ! 365: putchar(*cp); ! 366: continue; ! 367: } ! 368: printf("\\%03o", *cp); ! 369: n += 3; ! 370: } ! 371: } ! 372: putchar('\n'); ! 373: } ! 374: ! 375: /* ! 376: * Execute substitute command. ! 377: */ ! 378: execsub(sp) ! 379: SUB *sp; ! 380: { ! 381: register char *np; ! 382: register char *pp; ! 383: register int n; ! 384: register char *lp; ! 385: register char *rp; ! 386: register int nth; ! 387: register int len; ! 388: register int subflag; ! 389: register int subnths; ! 390: ! 391: subflag = 0; ! 392: subnths = sp->s_nth; ! 393: for (n=0; n<1+NBRC; n++) { ! 394: brcl[n].b_bp = NULL; ! 395: brcl[n].b_ep = NULL; ! 396: } ! 397: brcl[0].b_ep = pattbuf; ! 398: lp = pattbuf; ! 399: np = linebuf; ! 400: nth = 0; ! 401: for (;;) { ! 402: pp = sp->s_pat; ! 403: if (*pp == CSSOL) { ! 404: if (lp != pattbuf) ! 405: break; ! 406: pp++; ! 407: } ! 408: if ((pp=match(lp, pp)) == NULL) { ! 409: if (*lp++ == '\0') ! 410: break; ! 411: continue; ! 412: } ! 413: nth++; ! 414: if (subnths) { ! 415: if (nth < subnths) { ! 416: lp = pp; ! 417: continue; ! 418: } ! 419: if (nth > subnths) ! 420: goto done; ! 421: } ! 422: subflag = 1; ! 423: len = pp - lp; ! 424: brcl[0].b_bp = lp; ! 425: lp = pp; ! 426: pp = brcl[0].b_ep; ! 427: brcl[0].b_ep = lp; ! 428: n = brcl[0].b_bp - pp; ! 429: if (np+n >= &linebuf[LHPSIZE-1]) ! 430: goto ovf; ! 431: while (n--) ! 432: *np++ = *pp++; ! 433: rp = sp->s_rep; ! 434: while (*rp) { ! 435: if (np >= &linebuf[LHPSIZE-4]) ! 436: goto ovf; ! 437: if (*rp != '\\') { ! 438: *np++ = *rp++; ! 439: continue; ! 440: } ! 441: if (*++rp == '\\') { ! 442: *np++ = *rp++; ! 443: continue; ! 444: } ! 445: n = *rp++ - '0'; ! 446: if ((pp=brcl[n].b_bp) == NULL) ! 447: continue; ! 448: n = brcl[n].b_ep-pp; ! 449: if (np+n >= &linebuf[LHPSIZE-4]) ! 450: goto ovf; ! 451: while (n--) ! 452: *np++ = *pp++; ! 453: } ! 454: if (*lp == '\0') ! 455: break; ! 456: if (len == 0) ! 457: lp++; ! 458: if (subnths!=0 && nth==subnths) ! 459: break; ! 460: } ! 461: done: ! 462: pp = brcl[0].b_ep; ! 463: while (*pp) { ! 464: if (np >= &linebuf[LHPSIZE-1]) ! 465: goto ovf; ! 466: *np++ = *pp++; ! 467: } ! 468: *np++ = '\0'; ! 469: pattlen = n = np - linebuf; ! 470: pp = pattbuf; ! 471: np = linebuf; ! 472: do { ! 473: *pp++ = *np++; ! 474: } while (--n); ! 475: if (subflag) { ! 476: if (sp->s_cop) ! 477: printf("%s\n", pattbuf); ! 478: if (sp->s_fil) ! 479: fprintf(sp->s_fil->f_filp, "%s\n", pattbuf); ! 480: } ! 481: return (subflag); ! 482: ovf: ! 483: printc("Line buffer overflow"); ! 484: return (0); ! 485: } ! 486: ! 487: /* ! 488: * See if the compiled pattern `pat' matches the line in pattbuf. ! 489: */ ! 490: execute(pat) ! 491: char *pat; ! 492: { ! 493: register int i; ! 494: register char *lp, *ep; ! 495: ! 496: for (i=0; i<1+NBRC; i++) { ! 497: brcl[i].b_bp = NULL; ! 498: brcl[i].b_ep = NULL; ! 499: } ! 500: if (pat[0] == CSSOL) ! 501: ep = match(lp=pattbuf, &pat[1]); ! 502: else { ! 503: ep = NULL; ! 504: lp = pattbuf; ! 505: do { ! 506: if (ep=match(lp, pat)) ! 507: break; ! 508: } while (*lp++); ! 509: } ! 510: if (ep) { ! 511: brcl[0].b_bp = lp; ! 512: brcl[0].b_ep = ep; ! 513: } ! 514: return (ep ? 1 : 0); ! 515: } ! 516: ! 517: /* ! 518: * Given a pointer to a compiled expression, `cp', and a pointer to ! 519: * a line, `lp', return 1 if the expression matches, else 0. ! 520: */ ! 521: char * ! 522: match(lp, cp) ! 523: register char *lp, *cp; ! 524: { ! 525: register int n; ! 526: char *llp, *lcp; ! 527: ! 528: for (;;) { ! 529: switch (*cp++) { ! 530: case CSNUL: ! 531: return (lp); ! 532: case CSEOL: ! 533: if (*lp) ! 534: return (NULL); ! 535: return (lp); ! 536: case CSOPR: ! 537: brcl[*cp++].b_bp = lp; ! 538: continue; ! 539: case CSCPR: ! 540: brcl[*cp++].b_ep = lp; ! 541: continue; ! 542: case CSBRN: ! 543: n = *cp++; ! 544: lcp = cp; ! 545: cp = brcl[n].b_bp; ! 546: n = brcl[n].b_ep - cp; ! 547: if (n > LHPSIZE) ! 548: return (NULL); ! 549: while (n-- > 0) ! 550: if (*lp++ != *cp++) ! 551: return (NULL); ! 552: cp = lcp; ! 553: continue; ! 554: case CSDOT: ! 555: if (*lp++ == '\0') ! 556: return (NULL); ! 557: continue; ! 558: case CMDOT: ! 559: llp = lp; ! 560: while (*lp) ! 561: lp++; ! 562: goto star; ! 563: case CSCHR: ! 564: if (*cp++ != *lp++) ! 565: return (NULL); ! 566: continue; ! 567: case CMCHR: ! 568: llp = lp; ! 569: while (*cp == *lp) ! 570: lp++; ! 571: cp++; ! 572: goto star; ! 573: case CSSCC: ! 574: if (*cp++ == tolower(*lp++)) ! 575: continue; ! 576: return (NULL); ! 577: case CMSCC: ! 578: llp = lp; ! 579: while (*cp == tolower(*lp++)) ! 580: ; ! 581: cp++; ! 582: goto star; ! 583: case CSCCL: ! 584: n = *cp++; ! 585: while (*cp++ != *lp) ! 586: if (--n == 0) ! 587: return (NULL); ! 588: lp++; ! 589: cp += n-1; ! 590: continue; ! 591: case CMCCL: ! 592: llp = lp; ! 593: lcp = cp; ! 594: while (*lp) { ! 595: cp = lcp; ! 596: n = *cp++; ! 597: while (*cp++ != *lp) ! 598: if (--n == 0) ! 599: goto star; ! 600: lp++; ! 601: } ! 602: cp = lcp + *lcp + 1; ! 603: goto star; ! 604: case CSNCL: ! 605: if (*lp == '\0') ! 606: return (NULL); ! 607: n = *cp++; ! 608: while (n--) ! 609: if (*cp++ == *lp) ! 610: return (NULL); ! 611: lp++; ! 612: continue; ! 613: case CMNCL: ! 614: llp = lp; ! 615: lcp = cp; ! 616: while (*lp) { ! 617: cp = lcp; ! 618: n = *cp++; ! 619: while (n--) { ! 620: if (*cp++ == *lp) { ! 621: cp = lcp + *lcp + 1; ! 622: goto star; ! 623: } ! 624: } ! 625: lp++; ! 626: } ! 627: cp = lcp + *lcp + 1; ! 628: star: ! 629: do { ! 630: if (lcp=match(lp, cp)) ! 631: return (lcp); ! 632: } while (--lp >= llp); ! 633: return (NULL); ! 634: } ! 635: } ! 636: } ! 637: ! 638: ! 639: /* ! 640: * Print out an execution error message. ! 641: */ ! 642: printe(s) ! 643: { ! 644: fprintf(stderr, "%r", &s); ! 645: putc('\n', stderr); ! 646: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.