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