|
|
1.1 ! root 1: /* ! 2: * AWK ! 3: * Part 3 - execution of the compiled code. ! 4: */ ! 5: ! 6: #include "awk.h" ! 7: #include "y.tab.h" ! 8: ! 9: static CHAR *sb; /* String beginning -- evalre */ ! 10: static CHAR toodeep[] = "For/while nesting too deep"; ! 11: CHAR *reexec(); ! 12: ! 13: /* ! 14: * Called for each input file ! 15: * Also, called before the first file ! 16: * and after the last file. ! 17: * This routine executes the code for ! 18: * each input line. ! 19: */ ! 20: awk(np, fp, fn) ! 21: register NODE *np; ! 22: register FILE *fp; ! 23: CHAR *fn; ! 24: { ! 25: CHAR ibuf[MAXRECORD]; ! 26: ! 27: sassign(FILENAMEp, fn); ! 28: if (fp == NULL) { ! 29: lineno = 0; ! 30: execute(np, NULL); ! 31: } else { ! 32: if (fp != stdin) ! 33: setbuf(fp, inbuf); ! 34: lineno = 1; ! 35: setjmp(nextenv); ! 36: while (awkinput(ibuf, MAXRECORD, fp) != NULL) { ! 37: iassign(NRp, NRp->t_INT+1); ! 38: execute(np, ibuf); ! 39: } ! 40: if (fp != stdin) ! 41: fclose(fp); ! 42: } ! 43: } ! 44: ! 45: /* ! 46: * Read a record in for ! 47: * awk. ! 48: */ ! 49: STRING ! 50: awkinput(as, lim, fp) ! 51: STRING as; ! 52: unsigned lim; ! 53: register FILE *fp; ! 54: { ! 55: register int c; ! 56: register CHAR *s; ! 57: register int rs; ! 58: register STRING ret; ! 59: register int nf = 0; ! 60: register int spcflag = 0; ! 61: ! 62: if ((rs = RS[0]) == '\0') { ! 63: rs = '\n'; ! 64: spcflag++; ! 65: } ! 66: s = as; ! 67: while (--lim>0 && (c = getc(fp))!=EOF) { ! 68: if (c == '\n') ! 69: lineno++; ! 70: if (c == rs) ! 71: if (!spcflag || s==as || s[-1]=='\n') ! 72: break; ! 73: *s++ = c; ! 74: } ! 75: *s = '\0'; ! 76: ret = c==EOF && s==as ? NULL : as; ! 77: s = as; ! 78: if (whitesw) { ! 79: for (;;) { ! 80: while (FSMAP[c = *s]) /* pass spaces */ ! 81: s++; ! 82: if (c == '\0') /* if end of line no field */ ! 83: break; ! 84: nf++; ! 85: while ((c = *s) != '\0' && !FSMAP[c]) /* pass field */ ! 86: s++; ! 87: if (c == '\0') ! 88: break; ! 89: } ! 90: } ! 91: else if (*s) { ! 92: for (;;) { ! 93: nf++; ! 94: while ((c = *s) != '\0' && !FSMAP[c]) ! 95: s++; ! 96: if (c == '\0') ! 97: break; ! 98: if (FSMAP[c = *s]) /* pass delimeter */ ! 99: s++; ! 100: if (c == '\0') ! 101: break; ! 102: } ! 103: } ! 104: iassign(NFp, (INT)nf); ! 105: return (ret); ! 106: } ! 107: ! 108: /* ! 109: * This is the root of the execution tree ! 110: * that handles patterns and actions ! 111: * and lists of the above. ! 112: * `s' is the input string. ! 113: * Free all outstanding nodes accumulated ! 114: * during execution at the end of this ! 115: * routine (each input line). ! 116: */ ! 117: execute(np, s) ! 118: register NODE *np; ! 119: register STRING s; ! 120: { ! 121: register NODE *xp; ! 122: ! 123: inline = s; ! 124: while (np != NULL) { ! 125: if (np->n_op == ALIST) { ! 126: xp = np->n_O1; ! 127: np = np->n_O2; ! 128: } else { ! 129: xp = np; ! 130: np = NULL; ! 131: } ! 132: if (xp->n_op != AROOT) ! 133: awkerr("Bad op in execute %d", xp->n_op); ! 134: if (xp->n_O1 != NULL) { ! 135: if (evalpat(xp->n_O1)) ! 136: if (xp->n_O2 == NULL) { ! 137: if (!beginflag && !endflag) ! 138: xprint(&xfield0, NULL); ! 139: } else ! 140: evalact(xp->n_O2); ! 141: } else if (!beginflag && !endflag) ! 142: evalact(xp->n_O2); ! 143: } ! 144: while ((np = tempnodes) != NULL) { ! 145: tempnodes = np->t_next; ! 146: freenode(np); ! 147: } ! 148: if (inline != s) ! 149: free(inline); ! 150: } ! 151: ! 152: /* ! 153: * Evaluate the pattern half ! 154: * of the expression. ! 155: */ ! 156: evalpat(np) ! 157: register NODE *np; ! 158: { ! 159: register int ret = 0; ! 160: ! 161: if ((beginflag && np->n_op==ABEGIN) || (endflag && np->n_op==AEND)) ! 162: return (1); ! 163: if (beginflag || endflag) ! 164: return (0); ! 165: switch (np->n_op) { ! 166: case ABEGIN: ! 167: case AEND: ! 168: return (0); ! 169: ! 170: case ARANGE: ! 171: if (np->n_flag==0 && evalpat(np->n_O1)) { ! 172: np->n_flag++; ! 173: ret = 1; ! 174: } else if (np->n_flag == 1) { ! 175: if (evalpat(np->n_O2)) ! 176: np->n_flag = 0; ! 177: ret = 1; ! 178: } ! 179: break; ! 180: ! 181: default: ! 182: ret = evalint(np); ! 183: break; ! 184: } ! 185: return (ret); ! 186: } ! 187: ! 188: /* ! 189: * Evaluate the action part of the ! 190: * statement. ! 191: */ ! 192: evalact(anp) ! 193: register NODE *anp; ! 194: { ! 195: register NODE *np; ! 196: register int i; ! 197: ! 198: again: ! 199: if (anp == NULL) ! 200: return; ! 201: if (anp->n_op == ALIST) { ! 202: np = anp->n_O1; ! 203: anp = anp->n_O2; ! 204: } else { ! 205: np = anp; ! 206: anp = NULL; ! 207: } ! 208: switch (np->n_op) { ! 209: case AIF: ! 210: if (evalint(np->n_O1) != 0) ! 211: evalact(np->n_O2); ! 212: else if (np->n_O3 != NULL) ! 213: evalact(np->n_O3); ! 214: break; ! 215: ! 216: case AWHILE: ! 217: if (++fwlevel >= NNEST) ! 218: awkerr(toodeep); ! 219: while (evalint(np->n_O1) != 0) { ! 220: if ((i = setjmp(fwenv[fwlevel])) == ABREAK) ! 221: break; ! 222: else if (i == ACONTIN) ! 223: continue; ! 224: evalact(np->n_O2); ! 225: } ! 226: fwlevel--; ! 227: break; ! 228: ! 229: case AFOR: ! 230: if (++fwlevel >= NNEST) ! 231: awkerr(toodeep); ! 232: if (np->n_O1 != NULL) ! 233: evalact(np->n_O1); ! 234: for ( ; evalint(np->n_O2); evalact(np->n_O3)) { ! 235: if ((i = setjmp(fwenv[fwlevel])) == ABREAK) ! 236: break; ! 237: else if (i == ACONTIN) ! 238: continue; ! 239: evalact(np->n_O4); ! 240: } ! 241: fwlevel--; ! 242: break; ! 243: ! 244: case AFORIN: ! 245: if (++fwlevel >= NNEST) ! 246: awkerr(toodeep); ! 247: xforin(np->n_O1, np->n_O2, np->n_O3); ! 248: fwlevel--; ! 249: break; ! 250: ! 251: case ABREAK: ! 252: case ACONTIN: ! 253: i = np->n_op; ! 254: if (fwlevel < 0) ! 255: awkwarn("No for or while for %s", ! 256: i==ABREAK ? "break" : "continue"); ! 257: else ! 258: longjmp(fwenv[fwlevel], i); ! 259: break; ! 260: ! 261: case ANEXT: ! 262: longjmp(nextenv, 1); ! 263: break; ! 264: ! 265: case AEXIT: ! 266: if (!exitflag) ! 267: awkexit(0); ! 268: break; ! 269: ! 270: case APRINT: ! 271: xprint(np->n_O1, np->n_O2); ! 272: break; ! 273: ! 274: case APRINTF: ! 275: xprintf(np->n_O1, np->n_O2, NULL); ! 276: break; ! 277: ! 278: default: ! 279: evalexpr(np); ! 280: } ! 281: while ((np = tempnodes) != NULL) { ! 282: tempnodes = np->t_next; ! 283: freenode(np); ! 284: } ! 285: goto again; ! 286: } ! 287: ! 288: /* ! 289: * Evaluate an expression. ! 290: */ ! 291: NODE * ! 292: evalexpr(np) ! 293: register NODE *np; ! 294: { ! 295: register NODE *tnp; ! 296: register int i; ! 297: ! 298: switch (np->n_op) { ! 299: case ATERM: ! 300: break; ! 301: ! 302: case AARRAY: ! 303: np = xarray(np->n_O1, np->n_O2); ! 304: break; ! 305: ! 306: case AFIELD: ! 307: np = xfield((int)evalint(np->n_O1), NULL); ! 308: break; ! 309: ! 310: case AFUNC: ! 311: i = fnargs(tnp = np->n_O2); ! 312: np = np->n_O1; ! 313: if (i<np->t_MINARG || (np->t_MAXARG!=-1 && i>np->t_MAXARG)) ! 314: awkerr("Too %s arguments: %s", ! 315: i<np->t_MINARG ? "few" : "many", np->t_name); ! 316: np = (*np->t_FUNC)(tnp, i); ! 317: break; ! 318: ! 319: case AREMAT: ! 320: case ARENMAT: ! 321: i = evalre(np->n_O2, evalstring(np->n_O1)); ! 322: if (np->n_op == ARENMAT) ! 323: i = !i; ! 324: np = inode((INT)i); ! 325: break; ! 326: ! 327: case ARE: ! 328: np = inode((INT)evalre(np->n_O1, inline)); ! 329: break; ! 330: ! 331: case ACONC: ! 332: np = xconc(np->n_O1, np->n_O2); ! 333: break; ! 334: ! 335: case AADD: ! 336: np = xadd(evalexpr(np->n_O1), evalexpr(np->n_O2)); ! 337: break; ! 338: ! 339: case ASUB: ! 340: np = xsub(evalexpr(np->n_O1), evalexpr(np->n_O2)); ! 341: break; ! 342: ! 343: case AMUL: ! 344: np = xmul(evalexpr(np->n_O1), evalexpr(np->n_O2)); ! 345: break; ! 346: ! 347: case ANEG: ! 348: np = xneg(evalexpr(np->n_O1)); ! 349: break; ! 350: ! 351: case ADIV: ! 352: np = xdiv(evalexpr(np->n_O1), evalexpr(np->n_O2)); ! 353: break; ! 354: ! 355: case AMOD: ! 356: np = xmod(evalexpr(np->n_O1), evalexpr(np->n_O2)); ! 357: break; ! 358: ! 359: case AEQ: ! 360: case ANE: ! 361: case AGT: ! 362: case AGE: ! 363: case ALT: ! 364: case ALE: ! 365: np = xcmp(np->n_O1, np->n_O2, np->n_op); ! 366: break; ! 367: ! 368: case AOROR: ! 369: np = inode((INT)(evalint(np->n_O1) || evalint(np->n_O2))); ! 370: break; ! 371: ! 372: case AANDAND: ! 373: np = inode((INT)(evalint(np->n_O1) && evalint(np->n_O2))); ! 374: break; ! 375: ! 376: case ANOT: ! 377: np = inode((INT)(!evalint(np->n_O1))); ! 378: break; ! 379: ! 380: case AASGN: ! 381: np = xassign(np->n_O1, evalexpr(np->n_O2)); ! 382: break; ! 383: ! 384: case AINCA: ! 385: np = xinca(np->n_O1); ! 386: break; ! 387: ! 388: case ADECA: ! 389: np = xdeca(np->n_O1); ! 390: break; ! 391: ! 392: default: ! 393: awkerr("Bad op in evalexpr %d", np->n_op); ! 394: } ! 395: return (np); ! 396: } ! 397: ! 398: /* ! 399: * Evaluate an expression and ! 400: * return the resultant string. ! 401: */ ! 402: CHAR * ! 403: evalstring(np) ! 404: register NODE *np; ! 405: { ! 406: static CHAR numbuf[100]; ! 407: ! 408: np = evalexpr(np); ! 409: if (np->n_flag & T_NUM) { ! 410: if (np->n_flag & T_INT) ! 411: sprintf(numbuf, "%ld", np->t_INT); ! 412: else ! 413: sprintf(numbuf, "%.6g", np->t_FLOAT); ! 414: return (numbuf); ! 415: } else ! 416: return (np->t_STRING); ! 417: } ! 418: ! 419: /* ! 420: * Evaluate an expression and ! 421: * return the resultant INT. ! 422: */ ! 423: INT ! 424: evalint(np) ! 425: register NODE *np; ! 426: { ! 427: np = evalexpr(np); ! 428: if (np->n_flag & T_NUM) { ! 429: if (np->n_flag & T_INT) ! 430: return (np->t_INT); else ! 431: return (np->t_FLOAT); ! 432: } else ! 433: return (stoi(np->t_STRING)); ! 434: } ! 435: ! 436: /* ! 437: * Evaluate an expression and ! 438: * return the resultant FLOAT. ! 439: */ ! 440: FLOAT ! 441: evalfloat(np) ! 442: register NODE *np; ! 443: { ! 444: np = evalexpr(np); ! 445: if (np->n_flag & T_NUM) { ! 446: if (np->n_flag & T_INT) ! 447: return (np->t_INT); else ! 448: return (np->t_FLOAT); ! 449: } else ! 450: return (stof(np->t_STRING)); ! 451: } ! 452: ! 453: /* ! 454: * Called to evaluate a regular expression ! 455: * with the given string. ! 456: */ ! 457: evalre(np, s) ! 458: register NODE *np; ! 459: register CHAR *s; ! 460: { ! 461: sb = s; ! 462: if (np!=NULL && np->n_op==ARBOL) ! 463: return (reexec(np, s) != NULL); ! 464: s--; ! 465: do { ! 466: if (reexec(np, ++s) != NULL) ! 467: return (1); ! 468: } while (*s!='\n' && *s!='\0'); ! 469: return (0); ! 470: } ! 471: ! 472: /* ! 473: * Internal regular expression ! 474: * execution routines ! 475: */ ! 476: CHAR * ! 477: reexec(np, s) ! 478: register NODE *np; ! 479: register CHAR *s; ! 480: { ! 481: register c; ! 482: register CHAR *ss, *es; ! 483: ! 484: for ( ; np != NULL; np = np->n_O3) ! 485: switch (np->n_op) { ! 486: case ARBOL: ! 487: if (s != sb) ! 488: return (NULL); ! 489: break; ! 490: ! 491: case AREOL: ! 492: if (*s!='\n' && *s!='\0') ! 493: return (NULL); ! 494: break; ! 495: ! 496: case ARANY: ! 497: c = *s++; ! 498: if (c=='\n' || c=='\0') ! 499: return (NULL); ! 500: break; ! 501: ! 502: case ARDCHAR: ! 503: if (islower(np->n_o1.n_char)) { ! 504: if (isupper(c = *s++)) ! 505: c = tolower(c); ! 506: if (c != np->n_o1.n_char) ! 507: return (NULL); ! 508: break; ! 509: } ! 510: case ARCHAR: ! 511: c = *s++; ! 512: if (c != np->n_o1.n_char) ! 513: return (NULL); ! 514: break; ! 515: ! 516: case ARDCLASS: ! 517: if (isupper(c = *s++)) ! 518: c = tolower(c); ! 519: if ((np->n_o1.n_charp[c/NBPC] & (1<<(c%NBPC))) == 0) ! 520: return (NULL); ! 521: break; ! 522: ! 523: case ARCLASS: ! 524: c = *s++; ! 525: if ((np->n_o1.n_charp[c/NBPC] & (1<<(c%NBPC))) == 0) ! 526: return (NULL); ! 527: break; ! 528: ! 529: case AROR: ! 530: ss = s; ! 531: if ((s = reexec(np->n_O1, s)) == NULL) ! 532: if ((s = reexec(np->n_O2, ss))==NULL) ! 533: return (NULL); ! 534: break; ! 535: ! 536: case ARCLOS: ! 537: ss = s; ! 538: while ((es = reexec(np->n_O1, s)) != NULL) ! 539: s = es; ! 540: while (s >= ss) ! 541: if ((es = reexec(np->n_O3, s--))!=NULL) ! 542: return (es); ! 543: return (NULL); ! 544: ! 545: case ARNECL: ! 546: ss = s; ! 547: while ((es = reexec(np->n_O1, s)) != NULL) ! 548: s = es; ! 549: while (s > ss) ! 550: if ((es = reexec(np->n_O3, s--))!=NULL) ! 551: return (es); ! 552: return (NULL); ! 553: ! 554: case ARZOCL: ! 555: ss = s; ! 556: if ((es = reexec(np->n_O1, s)) != NULL) ! 557: s = es; ! 558: while (s >= ss) ! 559: if ((es = reexec(np->n_O3, s--))!=NULL) ! 560: return (es); ! 561: return (NULL); ! 562: ! 563: default: ! 564: awkerr("RE bad op %d", np->n_op); ! 565: } ! 566: return (s); ! 567: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.