1: #ifndef lint 2: static char sccsid[] = "@(#)run.c 4.5 12/4/84"; 3: #endif 4: 5: #include "awk.def" 6: #include "math.h" 7: #include "awk.h" 8: #include "stdio.h" 9: #define RECSIZE BUFSIZ 10: 11: #define FILENUM 10 12: struct 13: { 14: FILE *fp; 15: int type; 16: char *fname; 17: } files[FILENUM]; 18: FILE *popen(); 19: 20: extern obj execute(), nodetoobj(), fieldel(), dopa2(), gettemp(); 21: #define PA2NUM 29 22: int pairstack[PA2NUM], paircnt; 23: node *winner = (node *)NULL; 24: #define MAXTMP 20 25: cell tmps[MAXTMP]; 26: static cell nullval ={EMPTY,EMPTY,0.0,NUM,0}; 27: obj true ={ OBOOL, BTRUE, 0 }; 28: obj false ={ OBOOL, BFALSE, 0 }; 29: 30: run() 31: { 32: register int i; 33: 34: execute(winner); 35: 36: /* Wait for children to complete if output to a pipe. */ 37: for (i=0; i<FILENUM; i++) 38: if (files[i].fp && files[i].type == '|') 39: pclose(files[i].fp); 40: } 41: 42: obj execute(u) node *u; 43: { 44: register obj (*proc)(); 45: obj x; 46: node *a; 47: extern char *printname[]; 48: 49: if (u==(node *)NULL) 50: return(true); 51: for (a = u; ; a = a->nnext) { 52: if (cantexec(a)) 53: return(nodetoobj(a)); 54: if (a->ntype==NPA2) 55: proc=dopa2; 56: else { 57: if (notlegal(a->nobj)) 58: error(FATAL, "illegal statement %o", a); 59: proc = proctab[a->nobj-FIRSTTOKEN]; 60: } 61: x = (*proc)(a->narg,a->nobj); 62: if (isfld(x)) fldbld(); 63: if (isexpr(a)) 64: return(x); 65: /* a statement, goto next statement */ 66: if (isjump(x)) 67: return(x); 68: if (a->nnext == (node *)NULL) 69: return(x); 70: tempfree(x); 71: } 72: } 73: 74: obj program(a, n) node **a; 75: { 76: obj x; 77: 78: if (a[0] != NULL) { 79: x = execute(a[0]); 80: if (isexit(x)) 81: return(true); 82: if (isjump(x)) 83: error(FATAL, "unexpected break, continue or next"); 84: tempfree(x); 85: } 86: while (getrec()) { 87: x = execute(a[1]); 88: if (isexit(x)) break; 89: tempfree(x); 90: } 91: tempfree(x); 92: if (a[2] != NULL) { 93: x = execute(a[2]); 94: if (isbreak(x) || isnext(x) || iscont(x)) 95: error(FATAL, "unexpected break, continue or next"); 96: tempfree(x); 97: } 98: return(true); 99: } 100: 101: obj getline() 102: { 103: obj x; 104: 105: x = gettemp(); 106: setfval(x.optr, (awkfloat) getrec()); 107: return(x); 108: } 109: 110: obj array(a,n) node **a; 111: { 112: obj x, y; 113: extern obj arrayel(); 114: 115: x = execute(a[1]); 116: y = arrayel(a[0], x); 117: tempfree(x); 118: return(y); 119: } 120: 121: obj arrayel(a,b) node *a; obj b; 122: { 123: char *s; 124: cell *x; 125: int i; 126: obj y; 127: 128: s = getsval(b.optr); 129: x = (cell *) a; 130: if (!(x->tval&ARR)) { 131: strfree(x->sval); 132: x->tval &= ~STR; 133: x->tval |= ARR; 134: x->sval = (char *) makesymtab(); 135: } 136: y.optr = setsymtab(s, tostring(""), 0.0, STR|NUM, x->sval); 137: y.otype = OCELL; 138: y.osub = CVAR; 139: return(y); 140: } 141: 142: obj matchop(a,n) node **a; 143: { 144: obj x; 145: char *s; 146: int i; 147: 148: x = execute(a[0]); 149: if (isstr(x)) s = x.optr->sval; 150: else s = getsval(x.optr); 151: tempfree(x); 152: i = match(a[1], s); 153: if (n==MATCH && i==1 || n==NOTMATCH && i==0) 154: return(true); 155: else 156: return(false); 157: } 158: 159: obj boolop(a,n) node **a; 160: { 161: obj x, y; 162: int i; 163: 164: x = execute(a[0]); 165: i = istrue(x); 166: tempfree(x); 167: switch (n) { 168: default: 169: error(FATAL, "unknown boolean operator %d", n); 170: case BOR: 171: if (i) return(true); 172: y = execute(a[1]); 173: i = istrue(y); 174: tempfree(y); 175: if (i) return(true); 176: else return(false); 177: case AND: 178: if ( !i ) return(false); 179: y = execute(a[1]); 180: i = istrue(y); 181: tempfree(y); 182: if (i) return(true); 183: else return(false); 184: case NOT: 185: if (i) return(false); 186: else return(true); 187: } 188: } 189: 190: obj relop(a,n) node **a; 191: { 192: int i; 193: obj x, y; 194: awkfloat j; 195: 196: x = execute(a[0]); 197: y = execute(a[1]); 198: if (x.optr->tval&NUM && y.optr->tval&NUM) { 199: j = x.optr->fval - y.optr->fval; 200: i = j<0? -1: (j>0? 1: 0); 201: } else { 202: i = strcmp(getsval(x.optr), getsval(y.optr)); 203: } 204: tempfree(x); 205: tempfree(y); 206: switch (n) { 207: default: 208: error(FATAL, "unknown relational operator %d", n); 209: case LT: if (i<0) return(true); 210: else return(false); 211: case LE: if (i<=0) return(true); 212: else return(false); 213: case NE: if (i!=0) return(true); 214: else return(false); 215: case EQ: if (i==0) return(true); 216: else return(false); 217: case GE: if (i>=0) return(true); 218: else return(false); 219: case GT: if (i>0) return(true); 220: else return(false); 221: } 222: } 223: 224: tempfree(a) obj a; 225: { 226: if (!istemp(a)) return; 227: strfree(a.optr->sval); 228: a.optr->tval = 0; 229: } 230: 231: obj gettemp() 232: { 233: int i; 234: obj x; 235: 236: for (i=0; i<MAXTMP; i++) 237: if (tmps[i].tval==0) 238: break; 239: if (i==MAXTMP) 240: error(FATAL, "out of temporaries in gettemp"); 241: x.optr = &tmps[i]; 242: tmps[i] = nullval; 243: x.otype = OCELL; 244: x.osub = CTEMP; 245: return(x); 246: } 247: 248: obj indirect(a,n) node **a; 249: { 250: obj x; 251: int m; 252: cell *fieldadr(); 253: 254: x = execute(a[0]); 255: m = getfval(x.optr); 256: tempfree(x); 257: x.optr = fieldadr(m); 258: x.otype = OCELL; 259: x.osub = CFLD; 260: return(x); 261: } 262: 263: obj substr(a, nnn) node **a; 264: { 265: char *s, temp; 266: obj x; 267: int k, m, n; 268: 269: x = execute(a[0]); 270: s = getsval(x.optr); 271: k = strlen(s) + 1; 272: tempfree(x); 273: x = execute(a[1]); 274: m = getfval(x.optr); 275: if (m <= 0) 276: m = 1; 277: else if (m > k) 278: m = k; 279: tempfree(x); 280: if (a[2] != nullstat) { 281: x = execute(a[2]); 282: n = getfval(x.optr); 283: tempfree(x); 284: } 285: else 286: n = k - 1; 287: if (n < 0) 288: n = 0; 289: else if (n > k - m) 290: n = k - m; 291: dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s); 292: x = gettemp(); 293: temp = s[n+m-1]; /* with thanks to John Linderman */ 294: s[n+m-1] = '\0'; 295: setsval(x.optr, s + m - 1); 296: s[n+m-1] = temp; 297: return(x); 298: } 299: 300: obj sindex(a, nnn) node **a; 301: { 302: obj x; 303: char *s1, *s2, *p1, *p2, *q; 304: 305: x = execute(a[0]); 306: s1 = getsval(x.optr); 307: tempfree(x); 308: x = execute(a[1]); 309: s2 = getsval(x.optr); 310: tempfree(x); 311: 312: x = gettemp(); 313: for (p1 = s1; *p1 != '\0'; p1++) { 314: for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) 315: ; 316: if (*p2 == '\0') { 317: setfval(x.optr, (awkfloat) (p1 - s1 + 1)); /* origin 1 */ 318: return(x); 319: } 320: } 321: setfval(x.optr, 0.0); 322: return(x); 323: } 324: 325: char *format(s,a) char *s; node *a; 326: { 327: char *buf, *p, fmt[200], *t, *os; 328: obj x; 329: int flag = 0; 330: awkfloat xf; 331: 332: os = s; 333: p = buf = (char *)malloc(RECSIZE); 334: while (*s) { 335: if (*s != '%') { 336: *p++ = *s++; 337: continue; 338: } 339: if (*(s+1) == '%') { 340: *p++ = '%'; 341: s += 2; 342: continue; 343: } 344: for (t=fmt; (*t++ = *s) != '\0'; s++) 345: if (*s >= 'a' && *s <= 'z' && *s != 'l') 346: break; 347: *t = '\0'; 348: if (t >= fmt + sizeof(fmt)) 349: error(FATAL, "format item %.20s... too long", os); 350: switch (*s) { 351: case 'f': case 'e': case 'g': 352: flag = 1; 353: break; 354: case 'd': 355: flag = 2; 356: if(*(s-1) == 'l') break; 357: *(t-1) = 'l'; 358: *t = 'd'; 359: *++t = '\0'; 360: break; 361: case 'o': case 'x': 362: flag = *(s-1)=='l' ? 2 : 3; 363: break; 364: case 'c': 365: flag = 3; 366: break; 367: case 's': 368: flag = 4; 369: break; 370: default: 371: flag = 0; 372: break; 373: } 374: if (flag == 0) { 375: sprintf(p, "%s", fmt); 376: p += strlen(p); 377: continue; 378: } 379: if (a == NULL) 380: error(FATAL, "not enough arguments in printf(%s)", os); 381: x = execute(a); 382: a = a->nnext; 383: if (flag != 4) /* watch out for converting to numbers! */ 384: xf = getfval(x.optr); 385: if (flag==1) sprintf(p, fmt, xf); 386: else if (flag==2) sprintf(p, fmt, (long)xf); 387: else if (flag==3) sprintf(p, fmt, (int)xf); 388: else if (flag==4) sprintf(p, fmt, x.optr->sval==NULL ? "" : getsval(x.optr)); 389: tempfree(x); 390: p += strlen(p); 391: s++; 392: } 393: *p = '\0'; 394: return(buf); 395: } 396: 397: obj asprintf(a,n) node **a; 398: { 399: obj x; 400: node *y; 401: char *s; 402: 403: y = a[0]->nnext; 404: x = execute(a[0]); 405: s = format(getsval(x.optr), y); 406: tempfree(x); 407: x = gettemp(); 408: x.optr->sval = s; 409: x.optr->tval = STR; 410: return(x); 411: } 412: 413: obj arith(a,n) node **a; 414: { 415: awkfloat i,j; 416: obj x,y,z; 417: 418: x = execute(a[0]); 419: i = getfval(x.optr); 420: tempfree(x); 421: if (n != UMINUS) { 422: y = execute(a[1]); 423: j = getfval(y.optr); 424: tempfree(y); 425: } 426: z = gettemp(); 427: switch (n) { 428: default: 429: error(FATAL, "illegal arithmetic operator %d", n); 430: case ADD: 431: i += j; 432: break; 433: case MINUS: 434: i -= j; 435: break; 436: case MULT: 437: i *= j; 438: break; 439: case DIVIDE: 440: if (j == 0) 441: error(FATAL, "division by zero"); 442: i /= j; 443: break; 444: case MOD: 445: if (j == 0) 446: error(FATAL, "division by zero"); 447: i = i - j*(long)(i/j); 448: break; 449: case UMINUS: 450: i = -i; 451: break; 452: } 453: setfval(z.optr, i); 454: return(z); 455: } 456: 457: obj incrdecr(a, n) node **a; 458: { 459: obj x, z; 460: int k; 461: awkfloat xf; 462: 463: x = execute(a[0]); 464: xf = getfval(x.optr); 465: k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 466: if (n == PREINCR || n == PREDECR) { 467: setfval(x.optr, xf + k); 468: return(x); 469: } 470: z = gettemp(); 471: setfval(z.optr, xf); 472: setfval(x.optr, xf + k); 473: tempfree(x); 474: return(z); 475: } 476: 477: 478: obj assign(a,n) node **a; 479: { 480: obj x, y; 481: awkfloat xf, yf; 482: 483: x = execute(a[0]); 484: y = execute(a[1]); 485: if (n == ASSIGN) { /* ordinary assignment */ 486: if ((y.optr->tval & (STR|NUM)) == (STR|NUM)) { 487: setsval(x.optr, y.optr->sval); 488: x.optr->fval = y.optr->fval; 489: x.optr->tval |= NUM; 490: } 491: else if (y.optr->tval & STR) 492: setsval(x.optr, y.optr->sval); 493: else if (y.optr->tval & NUM) 494: setfval(x.optr, y.optr->fval); 495: tempfree(y); 496: return(x); 497: } 498: xf = getfval(x.optr); 499: yf = getfval(y.optr); 500: switch (n) { 501: case ADDEQ: 502: xf += yf; 503: break; 504: case SUBEQ: 505: xf -= yf; 506: break; 507: case MULTEQ: 508: xf *= yf; 509: break; 510: case DIVEQ: 511: if (yf == 0) 512: error(FATAL, "division by zero"); 513: xf /= yf; 514: break; 515: case MODEQ: 516: if (yf == 0) 517: error(FATAL, "division by zero"); 518: xf = xf - yf*(long)(xf/yf); 519: break; 520: default: 521: error(FATAL, "illegal assignment operator %d", n); 522: break; 523: } 524: tempfree(y); 525: setfval(x.optr, xf); 526: return(x); 527: } 528: 529: obj cat(a,q) node **a; 530: { 531: obj x,y,z; 532: int n1, n2; 533: char *s; 534: 535: x = execute(a[0]); 536: y = execute(a[1]); 537: getsval(x.optr); 538: getsval(y.optr); 539: n1 = strlen(x.optr->sval); 540: n2 = strlen(y.optr->sval); 541: s = (char *) malloc(n1 + n2 + 1); 542: strcpy(s, x.optr->sval); 543: strcpy(s+n1, y.optr->sval); 544: tempfree(y); 545: z = gettemp(); 546: z.optr->sval = s; 547: z.optr->tval = STR; 548: tempfree(x); 549: return(z); 550: } 551: 552: obj pastat(a,n) node **a; 553: { 554: obj x; 555: 556: if (a[0]==nullstat) 557: x = true; 558: else 559: x = execute(a[0]); 560: if (istrue(x)) { 561: tempfree(x); 562: x = execute(a[1]); 563: } 564: return(x); 565: } 566: 567: obj dopa2(a,n) node **a; 568: { 569: obj x; 570: 571: if (pairstack[n]==0) { 572: x = execute(a[0]); 573: if (istrue(x)) 574: pairstack[n] = 1; 575: tempfree(x); 576: } 577: if (pairstack[n] == 1) { 578: x = execute(a[1]); 579: if (istrue(x)) 580: pairstack[n] = 0; 581: tempfree(x); 582: x = execute(a[2]); 583: return(x); 584: } 585: return(false); 586: } 587: 588: obj aprintf(a,n) node **a; 589: { 590: obj x; 591: 592: x = asprintf(a,n); 593: if (a[1]==NULL) { 594: printf("%s", x.optr->sval); 595: tempfree(x); 596: return(true); 597: } 598: redirprint(x.optr->sval, (int)a[1], a[2]); 599: return(x); 600: } 601: 602: obj split(a,nnn) node **a; 603: { 604: obj x; 605: cell *ap; 606: register char *s, *p; 607: char *t, temp, num[5]; 608: register int sep; 609: int n, flag; 610: 611: x = execute(a[0]); 612: s = getsval(x.optr); 613: tempfree(x); 614: if (a[2] == nullstat) 615: sep = **FS; 616: else { 617: x = execute(a[2]); 618: sep = getsval(x.optr)[0]; 619: tempfree(x); 620: } 621: ap = (cell *) a[1]; 622: freesymtab(ap); 623: dprintf("split: s=|%s|, a=%s, sep=|%c|\n", s, ap->nval, sep); 624: ap->tval &= ~STR; 625: ap->tval |= ARR; 626: ap->sval = (char *) makesymtab(); 627: 628: n = 0; 629: if (sep == ' ') 630: for (n = 0; ; ) { 631: while (*s == ' ' || *s == '\t' || *s == '\n') 632: s++; 633: if (*s == 0) 634: break; 635: n++; 636: t = s; 637: do 638: s++; 639: while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); 640: temp = *s; 641: *s = '\0'; 642: sprintf(num, "%d", n); 643: if (isnumber(t)) 644: setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval); 645: else 646: setsymtab(num, tostring(t), 0.0, STR, ap->sval); 647: *s = temp; 648: if (*s != 0) 649: s++; 650: } 651: else if (*s != 0) 652: for (;;) { 653: n++; 654: t = s; 655: while (*s != sep && *s != '\n' && *s != '\0') 656: s++; 657: temp = *s; 658: *s = '\0'; 659: sprintf(num, "%d", n); 660: if (isnumber(t)) 661: setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval); 662: else 663: setsymtab(num, tostring(t), 0.0, STR, ap->sval); 664: *s = temp; 665: if (*s++ == 0) 666: break; 667: } 668: x = gettemp(); 669: x.optr->tval = NUM; 670: x.optr->fval = n; 671: return(x); 672: } 673: 674: obj ifstat(a,n) node **a; 675: { 676: obj x; 677: 678: x = execute(a[0]); 679: if (istrue(x)) { 680: tempfree(x); 681: x = execute(a[1]); 682: } 683: else if (a[2] != nullstat) { 684: tempfree(x); 685: x = execute(a[2]); 686: } 687: return(x); 688: } 689: 690: obj whilestat(a,n) node **a; 691: { 692: obj x; 693: 694: for (;;) { 695: x = execute(a[0]); 696: if (!istrue(x)) return(x); 697: tempfree(x); 698: x = execute(a[1]); 699: if (isbreak(x)) { 700: x = true; 701: return(x); 702: } 703: if (isnext(x) || isexit(x)) 704: return(x); 705: tempfree(x); 706: } 707: } 708: 709: obj forstat(a,n) node **a; 710: { 711: obj x; 712: 713: tempfree(execute(a[0])); 714: for (;;) { 715: if (a[1]!=nullstat) { 716: x = execute(a[1]); 717: if (!istrue(x)) return(x); 718: else tempfree(x); 719: } 720: x = execute(a[3]); 721: if (isbreak(x)) { /* turn off break */ 722: x = true; 723: return(x); 724: } 725: if (isnext(x) || isexit(x)) 726: return(x); 727: tempfree(x); 728: tempfree(execute(a[2])); 729: } 730: } 731: 732: obj instat(a, n) node **a; 733: { 734: cell *vp, *arrayp, *cp, **tp; 735: obj x; 736: int i; 737: 738: vp = (cell *) a[0]; 739: arrayp = (cell *) a[1]; 740: if (!(arrayp->tval & ARR)) 741: error(FATAL, "%s is not an array", arrayp->nval); 742: tp = (cell **) arrayp->sval; 743: for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */ 744: for (cp = tp[i]; cp != NULL; cp = cp->nextval) { 745: setsval(vp, cp->nval); 746: x = execute(a[2]); 747: if (isbreak(x)) { 748: x = true; 749: return(x); 750: } 751: if (isnext(x) || isexit(x)) 752: return(x); 753: tempfree(x); 754: } 755: } 756: return (true); 757: } 758: 759: obj jump(a,n) node **a; 760: { 761: obj x, y; 762: 763: x.otype = OJUMP; 764: switch (n) { 765: default: 766: error(FATAL, "illegal jump type %d", n); 767: break; 768: case EXIT: 769: if (a[0] != 0) { 770: y = execute(a[0]); 771: errorflag = getfval(y.optr); 772: } 773: x.osub = JEXIT; 774: break; 775: case NEXT: 776: x.osub = JNEXT; 777: break; 778: case BREAK: 779: x.osub = JBREAK; 780: break; 781: case CONTINUE: 782: x.osub = JCONT; 783: break; 784: } 785: return(x); 786: } 787: 788: obj fncn(a,n) node **a; 789: { 790: obj x; 791: awkfloat u; 792: int t; 793: 794: t = (int) a[0]; 795: x = execute(a[1]); 796: if (t == FLENGTH) 797: u = (awkfloat) strlen(getsval(x.optr)); 798: else if (t == FLOG) 799: u = log(getfval(x.optr)); 800: else if (t == FINT) 801: u = (awkfloat) (long) getfval(x.optr); 802: else if (t == FEXP) 803: u = exp(getfval(x.optr)); 804: else if (t == FSQRT) 805: u = sqrt(getfval(x.optr)); 806: else 807: error(FATAL, "illegal function type %d", t); 808: tempfree(x); 809: x = gettemp(); 810: setfval(x.optr, u); 811: return(x); 812: } 813: 814: obj print(a,n) node **a; 815: { 816: register node *x; 817: obj y; 818: char s[RECSIZE]; 819: 820: s[0] = '\0'; 821: for (x=a[0]; x!=NULL; x=x->nnext) { 822: y = execute(x); 823: strcat(s, getsval(y.optr)); 824: tempfree(y); 825: if (x->nnext==NULL) 826: strcat(s, *ORS); 827: else 828: strcat(s, *OFS); 829: } 830: if (strlen(s) >= RECSIZE) 831: error(FATAL, "string %.20s ... too long to print", s); 832: if (a[1]==nullstat) { 833: printf("%s", s); 834: return(true); 835: } 836: redirprint(s, (int)a[1], a[2]); 837: return(false); 838: } 839: 840: obj nullproc() {} 841: 842: obj nodetoobj(a) node *a; 843: { 844: obj x; 845: 846: x.optr = (cell *) a->nobj; 847: x.otype = OCELL; 848: x.osub = a->subtype; 849: if (isfld(x)) fldbld(); 850: return(x); 851: } 852: 853: redirprint(s, a, b) char *s; node *b; 854: { 855: register int i; 856: obj x; 857: 858: x = execute(b); 859: getsval(x.optr); 860: for (i=0; i<FILENUM; i++) 861: if (files[i].fp && strcmp(x.optr->sval, files[i].fname) == 0) 862: goto doit; 863: for (i=0; i<FILENUM; i++) 864: if (files[i].fp == 0) 865: break; 866: if (i >= FILENUM) 867: error(FATAL, "too many output files %d", i); 868: if (a == '|') /* a pipe! */ 869: files[i].fp = popen(x.optr->sval, "w"); 870: else if (a == APPEND) 871: files[i].fp = fopen(x.optr->sval, "a"); 872: else 873: files[i].fp = fopen(x.optr->sval, "w"); 874: if (files[i].fp == NULL) 875: error(FATAL, "can't open file %s", x.optr->sval); 876: files[i].fname = tostring(x.optr->sval); 877: files[i].type = a; 878: doit: 879: fprintf(files[i].fp, "%s", s); 880: #ifndef gcos 881: fflush(files[i].fp); /* in case someone is waiting for the output */ 882: #endif 883: tempfree(x); 884: }