114474Ssam #ifndef lint 2*17457Sralph static char sccsid[] = "@(#)run.c 4.5 12/04/84"; 314474Ssam #endif 46676Smckusick 56676Smckusick #include "awk.def" 66676Smckusick #include "math.h" 76676Smckusick #include "awk.h" 86676Smckusick #include "stdio.h" 913177Ssam #define RECSIZE BUFSIZ 106676Smckusick 116676Smckusick #define FILENUM 10 126676Smckusick struct 136676Smckusick { 146676Smckusick FILE *fp; 15*17457Sralph int type; 166676Smckusick char *fname; 176676Smckusick } files[FILENUM]; 186676Smckusick FILE *popen(); 196676Smckusick 206676Smckusick extern obj execute(), nodetoobj(), fieldel(), dopa2(), gettemp(); 216676Smckusick #define PA2NUM 29 226676Smckusick int pairstack[PA2NUM], paircnt; 236676Smckusick node *winner = (node *)NULL; 246676Smckusick #define MAXTMP 20 256676Smckusick cell tmps[MAXTMP]; 2610794Ssam static cell nullval ={EMPTY,EMPTY,0.0,NUM,0}; 276676Smckusick obj true ={ OBOOL, BTRUE, 0 }; 286676Smckusick obj false ={ OBOOL, BFALSE, 0 }; 296676Smckusick 306676Smckusick run() 316676Smckusick { 32*17457Sralph register int i; 33*17457Sralph 346676Smckusick execute(winner); 35*17457Sralph 36*17457Sralph /* Wait for children to complete if output to a pipe. */ 37*17457Sralph for (i=0; i<FILENUM; i++) 38*17457Sralph if (files[i].fp && files[i].type == '|') 39*17457Sralph pclose(files[i].fp); 406676Smckusick } 416676Smckusick 426676Smckusick obj execute(u) node *u; 436676Smckusick { 446676Smckusick register obj (*proc)(); 456676Smckusick obj x; 466676Smckusick node *a; 476676Smckusick extern char *printname[]; 486676Smckusick 496676Smckusick if (u==(node *)NULL) 506676Smckusick return(true); 516676Smckusick for (a = u; ; a = a->nnext) { 526676Smckusick if (cantexec(a)) 536676Smckusick return(nodetoobj(a)); 546676Smckusick if (a->ntype==NPA2) 556676Smckusick proc=dopa2; 566676Smckusick else { 576676Smckusick if (notlegal(a->nobj)) 586676Smckusick error(FATAL, "illegal statement %o", a); 596676Smckusick proc = proctab[a->nobj-FIRSTTOKEN]; 606676Smckusick } 616676Smckusick x = (*proc)(a->narg,a->nobj); 626676Smckusick if (isfld(x)) fldbld(); 636676Smckusick if (isexpr(a)) 646676Smckusick return(x); 656676Smckusick /* a statement, goto next statement */ 666676Smckusick if (isjump(x)) 676676Smckusick return(x); 686676Smckusick if (a->nnext == (node *)NULL) 696676Smckusick return(x); 706676Smckusick tempfree(x); 716676Smckusick } 726676Smckusick } 736676Smckusick 746676Smckusick obj program(a, n) node **a; 756676Smckusick { 766676Smckusick obj x; 776676Smckusick 786676Smckusick if (a[0] != NULL) { 796676Smckusick x = execute(a[0]); 806676Smckusick if (isexit(x)) 816676Smckusick return(true); 826676Smckusick if (isjump(x)) 836676Smckusick error(FATAL, "unexpected break, continue or next"); 846676Smckusick tempfree(x); 856676Smckusick } 866676Smckusick while (getrec()) { 876676Smckusick x = execute(a[1]); 886676Smckusick if (isexit(x)) break; 896676Smckusick tempfree(x); 906676Smckusick } 916676Smckusick tempfree(x); 926676Smckusick if (a[2] != NULL) { 936676Smckusick x = execute(a[2]); 946676Smckusick if (isbreak(x) || isnext(x) || iscont(x)) 956676Smckusick error(FATAL, "unexpected break, continue or next"); 966676Smckusick tempfree(x); 976676Smckusick } 986676Smckusick return(true); 996676Smckusick } 1006676Smckusick 1016676Smckusick obj getline() 1026676Smckusick { 1036676Smckusick obj x; 1046676Smckusick 1056676Smckusick x = gettemp(); 1066676Smckusick setfval(x.optr, (awkfloat) getrec()); 1076676Smckusick return(x); 1086676Smckusick } 1096676Smckusick 1106676Smckusick obj array(a,n) node **a; 1116676Smckusick { 1126676Smckusick obj x, y; 1136676Smckusick extern obj arrayel(); 1146676Smckusick 1156676Smckusick x = execute(a[1]); 1166676Smckusick y = arrayel(a[0], x); 1176676Smckusick tempfree(x); 1186676Smckusick return(y); 1196676Smckusick } 1206676Smckusick 1216676Smckusick obj arrayel(a,b) node *a; obj b; 1226676Smckusick { 1236676Smckusick char *s; 1246676Smckusick cell *x; 1256676Smckusick int i; 1266676Smckusick obj y; 1276676Smckusick 1286676Smckusick s = getsval(b.optr); 1296676Smckusick x = (cell *) a; 1306676Smckusick if (!(x->tval&ARR)) { 13110794Ssam strfree(x->sval); 1326676Smckusick x->tval &= ~STR; 1336676Smckusick x->tval |= ARR; 1346676Smckusick x->sval = (char *) makesymtab(); 1356676Smckusick } 1366676Smckusick y.optr = setsymtab(s, tostring(""), 0.0, STR|NUM, x->sval); 1376676Smckusick y.otype = OCELL; 1386676Smckusick y.osub = CVAR; 1396676Smckusick return(y); 1406676Smckusick } 1416676Smckusick 1426676Smckusick obj matchop(a,n) node **a; 1436676Smckusick { 1446676Smckusick obj x; 1456676Smckusick char *s; 1466676Smckusick int i; 1476676Smckusick 1486676Smckusick x = execute(a[0]); 1496676Smckusick if (isstr(x)) s = x.optr->sval; 1506676Smckusick else s = getsval(x.optr); 1516676Smckusick tempfree(x); 1526676Smckusick i = match(a[1], s); 1536676Smckusick if (n==MATCH && i==1 || n==NOTMATCH && i==0) 1546676Smckusick return(true); 1556676Smckusick else 1566676Smckusick return(false); 1576676Smckusick } 1586676Smckusick 1596676Smckusick obj boolop(a,n) node **a; 1606676Smckusick { 1616676Smckusick obj x, y; 1626676Smckusick int i; 1636676Smckusick 1646676Smckusick x = execute(a[0]); 1656676Smckusick i = istrue(x); 1666676Smckusick tempfree(x); 1676676Smckusick switch (n) { 1686676Smckusick default: 1696676Smckusick error(FATAL, "unknown boolean operator %d", n); 1706676Smckusick case BOR: 1716676Smckusick if (i) return(true); 1726676Smckusick y = execute(a[1]); 1736676Smckusick i = istrue(y); 1746676Smckusick tempfree(y); 1756676Smckusick if (i) return(true); 1766676Smckusick else return(false); 1776676Smckusick case AND: 1786676Smckusick if ( !i ) return(false); 1796676Smckusick y = execute(a[1]); 1806676Smckusick i = istrue(y); 1816676Smckusick tempfree(y); 1826676Smckusick if (i) return(true); 1836676Smckusick else return(false); 1846676Smckusick case NOT: 1856676Smckusick if (i) return(false); 1866676Smckusick else return(true); 1876676Smckusick } 1886676Smckusick } 1896676Smckusick 1906676Smckusick obj relop(a,n) node **a; 1916676Smckusick { 1926676Smckusick int i; 1936676Smckusick obj x, y; 1946676Smckusick awkfloat j; 1956676Smckusick 1966676Smckusick x = execute(a[0]); 1976676Smckusick y = execute(a[1]); 1986676Smckusick if (x.optr->tval&NUM && y.optr->tval&NUM) { 1996676Smckusick j = x.optr->fval - y.optr->fval; 2006676Smckusick i = j<0? -1: (j>0? 1: 0); 2016676Smckusick } else { 2026676Smckusick i = strcmp(getsval(x.optr), getsval(y.optr)); 2036676Smckusick } 2046676Smckusick tempfree(x); 2056676Smckusick tempfree(y); 2066676Smckusick switch (n) { 2076676Smckusick default: 2086676Smckusick error(FATAL, "unknown relational operator %d", n); 2096676Smckusick case LT: if (i<0) return(true); 2106676Smckusick else return(false); 2116676Smckusick case LE: if (i<=0) return(true); 2126676Smckusick else return(false); 2136676Smckusick case NE: if (i!=0) return(true); 2146676Smckusick else return(false); 2156676Smckusick case EQ: if (i==0) return(true); 2166676Smckusick else return(false); 2176676Smckusick case GE: if (i>=0) return(true); 2186676Smckusick else return(false); 2196676Smckusick case GT: if (i>0) return(true); 2206676Smckusick else return(false); 2216676Smckusick } 2226676Smckusick } 2236676Smckusick 2246676Smckusick tempfree(a) obj a; 2256676Smckusick { 2266676Smckusick if (!istemp(a)) return; 22710794Ssam strfree(a.optr->sval); 2286676Smckusick a.optr->tval = 0; 2296676Smckusick } 2306676Smckusick 2316676Smckusick obj gettemp() 2326676Smckusick { 2336676Smckusick int i; 2346676Smckusick obj x; 2356676Smckusick 2366676Smckusick for (i=0; i<MAXTMP; i++) 2376676Smckusick if (tmps[i].tval==0) 2386676Smckusick break; 2396676Smckusick if (i==MAXTMP) 2406676Smckusick error(FATAL, "out of temporaries in gettemp"); 2416676Smckusick x.optr = &tmps[i]; 2426676Smckusick tmps[i] = nullval; 2436676Smckusick x.otype = OCELL; 2446676Smckusick x.osub = CTEMP; 2456676Smckusick return(x); 2466676Smckusick } 2476676Smckusick 2486676Smckusick obj indirect(a,n) node **a; 2496676Smckusick { 2506676Smckusick obj x; 2516676Smckusick int m; 2526676Smckusick cell *fieldadr(); 2536676Smckusick 2546676Smckusick x = execute(a[0]); 2556676Smckusick m = getfval(x.optr); 2566676Smckusick tempfree(x); 2576676Smckusick x.optr = fieldadr(m); 2586676Smckusick x.otype = OCELL; 2596676Smckusick x.osub = CFLD; 2606676Smckusick return(x); 2616676Smckusick } 2626676Smckusick 2636676Smckusick obj substr(a, nnn) node **a; 2646676Smckusick { 2656676Smckusick char *s, temp; 2666676Smckusick obj x; 2676676Smckusick int k, m, n; 2686676Smckusick 2696676Smckusick x = execute(a[0]); 2706676Smckusick s = getsval(x.optr); 2716676Smckusick k = strlen(s) + 1; 2726676Smckusick tempfree(x); 2736676Smckusick x = execute(a[1]); 2746676Smckusick m = getfval(x.optr); 2756676Smckusick if (m <= 0) 2766676Smckusick m = 1; 2776676Smckusick else if (m > k) 2786676Smckusick m = k; 2796676Smckusick tempfree(x); 2806676Smckusick if (a[2] != nullstat) { 2816676Smckusick x = execute(a[2]); 2826676Smckusick n = getfval(x.optr); 2836676Smckusick tempfree(x); 2846676Smckusick } 2856676Smckusick else 2866676Smckusick n = k - 1; 2876676Smckusick if (n < 0) 2886676Smckusick n = 0; 2896676Smckusick else if (n > k - m) 2906676Smckusick n = k - m; 2916676Smckusick dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s); 2926676Smckusick x = gettemp(); 2936676Smckusick temp = s[n+m-1]; /* with thanks to John Linderman */ 2946676Smckusick s[n+m-1] = '\0'; 2956676Smckusick setsval(x.optr, s + m - 1); 2966676Smckusick s[n+m-1] = temp; 2976676Smckusick return(x); 2986676Smckusick } 2996676Smckusick 3006676Smckusick obj sindex(a, nnn) node **a; 3016676Smckusick { 3026676Smckusick obj x; 3036676Smckusick char *s1, *s2, *p1, *p2, *q; 3046676Smckusick 3056676Smckusick x = execute(a[0]); 3066676Smckusick s1 = getsval(x.optr); 3076676Smckusick tempfree(x); 3086676Smckusick x = execute(a[1]); 3096676Smckusick s2 = getsval(x.optr); 3106676Smckusick tempfree(x); 3116676Smckusick 3126676Smckusick x = gettemp(); 3136676Smckusick for (p1 = s1; *p1 != '\0'; p1++) { 3146676Smckusick for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) 3156676Smckusick ; 3166676Smckusick if (*p2 == '\0') { 3176676Smckusick setfval(x.optr, (awkfloat) (p1 - s1 + 1)); /* origin 1 */ 3186676Smckusick return(x); 3196676Smckusick } 3206676Smckusick } 3216676Smckusick setfval(x.optr, 0.0); 3226676Smckusick return(x); 3236676Smckusick } 3246676Smckusick 3256676Smckusick char *format(s,a) char *s; node *a; 3266676Smckusick { 3276676Smckusick char *buf, *p, fmt[200], *t, *os; 3286676Smckusick obj x; 3296676Smckusick int flag = 0; 3306676Smckusick awkfloat xf; 3316676Smckusick 3326676Smckusick os = s; 3336676Smckusick p = buf = (char *)malloc(RECSIZE); 3346676Smckusick while (*s) { 3356676Smckusick if (*s != '%') { 3366676Smckusick *p++ = *s++; 3376676Smckusick continue; 3386676Smckusick } 3396676Smckusick if (*(s+1) == '%') { 3406676Smckusick *p++ = '%'; 3416676Smckusick s += 2; 3426676Smckusick continue; 3436676Smckusick } 3446676Smckusick for (t=fmt; (*t++ = *s) != '\0'; s++) 3456676Smckusick if (*s >= 'a' && *s <= 'z' && *s != 'l') 3466676Smckusick break; 3476676Smckusick *t = '\0'; 3486676Smckusick if (t >= fmt + sizeof(fmt)) 3496676Smckusick error(FATAL, "format item %.20s... too long", os); 3506676Smckusick switch (*s) { 3516676Smckusick case 'f': case 'e': case 'g': 3526676Smckusick flag = 1; 3536676Smckusick break; 3546676Smckusick case 'd': 3556676Smckusick flag = 2; 3566676Smckusick if(*(s-1) == 'l') break; 3576676Smckusick *(t-1) = 'l'; 3586676Smckusick *t = 'd'; 3596676Smckusick *++t = '\0'; 3606676Smckusick break; 3616676Smckusick case 'o': case 'x': 3626676Smckusick flag = *(s-1)=='l' ? 2 : 3; 3636676Smckusick break; 3646676Smckusick case 'c': 3656676Smckusick flag = 3; 3666676Smckusick break; 3676676Smckusick case 's': 3686676Smckusick flag = 4; 3696676Smckusick break; 3706676Smckusick default: 3716676Smckusick flag = 0; 3726676Smckusick break; 3736676Smckusick } 3746676Smckusick if (flag == 0) { 3756676Smckusick sprintf(p, "%s", fmt); 3766676Smckusick p += strlen(p); 3776676Smckusick continue; 3786676Smckusick } 3796676Smckusick if (a == NULL) 3806676Smckusick error(FATAL, "not enough arguments in printf(%s)", os); 3816676Smckusick x = execute(a); 3826676Smckusick a = a->nnext; 3836676Smckusick if (flag != 4) /* watch out for converting to numbers! */ 3846676Smckusick xf = getfval(x.optr); 3856676Smckusick if (flag==1) sprintf(p, fmt, xf); 3866676Smckusick else if (flag==2) sprintf(p, fmt, (long)xf); 3876676Smckusick else if (flag==3) sprintf(p, fmt, (int)xf); 3886676Smckusick else if (flag==4) sprintf(p, fmt, x.optr->sval==NULL ? "" : getsval(x.optr)); 3896676Smckusick tempfree(x); 3906676Smckusick p += strlen(p); 3916676Smckusick s++; 3926676Smckusick } 3936676Smckusick *p = '\0'; 3946676Smckusick return(buf); 3956676Smckusick } 3966676Smckusick 3976676Smckusick obj asprintf(a,n) node **a; 3986676Smckusick { 3996676Smckusick obj x; 4006676Smckusick node *y; 4016676Smckusick char *s; 4026676Smckusick 4036676Smckusick y = a[0]->nnext; 4046676Smckusick x = execute(a[0]); 4056676Smckusick s = format(getsval(x.optr), y); 4066676Smckusick tempfree(x); 4076676Smckusick x = gettemp(); 4086676Smckusick x.optr->sval = s; 4096676Smckusick x.optr->tval = STR; 4106676Smckusick return(x); 4116676Smckusick } 4126676Smckusick 4136676Smckusick obj arith(a,n) node **a; 4146676Smckusick { 4156676Smckusick awkfloat i,j; 4166676Smckusick obj x,y,z; 4176676Smckusick 4186676Smckusick x = execute(a[0]); 4196676Smckusick i = getfval(x.optr); 4206676Smckusick tempfree(x); 4216676Smckusick if (n != UMINUS) { 4226676Smckusick y = execute(a[1]); 4236676Smckusick j = getfval(y.optr); 4246676Smckusick tempfree(y); 4256676Smckusick } 4266676Smckusick z = gettemp(); 4276676Smckusick switch (n) { 4286676Smckusick default: 4296676Smckusick error(FATAL, "illegal arithmetic operator %d", n); 4306676Smckusick case ADD: 4316676Smckusick i += j; 4326676Smckusick break; 4336676Smckusick case MINUS: 4346676Smckusick i -= j; 4356676Smckusick break; 4366676Smckusick case MULT: 4376676Smckusick i *= j; 4386676Smckusick break; 4396676Smckusick case DIVIDE: 4406676Smckusick if (j == 0) 4416676Smckusick error(FATAL, "division by zero"); 4426676Smckusick i /= j; 4436676Smckusick break; 4446676Smckusick case MOD: 4456676Smckusick if (j == 0) 4466676Smckusick error(FATAL, "division by zero"); 4476676Smckusick i = i - j*(long)(i/j); 4486676Smckusick break; 4496676Smckusick case UMINUS: 4506676Smckusick i = -i; 4516676Smckusick break; 4526676Smckusick } 4536676Smckusick setfval(z.optr, i); 4546676Smckusick return(z); 4556676Smckusick } 4566676Smckusick 4576676Smckusick obj incrdecr(a, n) node **a; 4586676Smckusick { 4596676Smckusick obj x, z; 4606676Smckusick int k; 4616676Smckusick awkfloat xf; 4626676Smckusick 4636676Smckusick x = execute(a[0]); 4646676Smckusick xf = getfval(x.optr); 4656676Smckusick k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 4666676Smckusick if (n == PREINCR || n == PREDECR) { 4676676Smckusick setfval(x.optr, xf + k); 4686676Smckusick return(x); 4696676Smckusick } 4706676Smckusick z = gettemp(); 4716676Smckusick setfval(z.optr, xf); 4726676Smckusick setfval(x.optr, xf + k); 4736676Smckusick tempfree(x); 4746676Smckusick return(z); 4756676Smckusick } 4766676Smckusick 4776676Smckusick 4786676Smckusick obj assign(a,n) node **a; 4796676Smckusick { 4806676Smckusick obj x, y; 4816676Smckusick awkfloat xf, yf; 4826676Smckusick 4836676Smckusick x = execute(a[0]); 4846676Smckusick y = execute(a[1]); 4856676Smckusick if (n == ASSIGN) { /* ordinary assignment */ 4866676Smckusick if ((y.optr->tval & (STR|NUM)) == (STR|NUM)) { 4876676Smckusick setsval(x.optr, y.optr->sval); 4886676Smckusick x.optr->fval = y.optr->fval; 4896676Smckusick x.optr->tval |= NUM; 4906676Smckusick } 4916676Smckusick else if (y.optr->tval & STR) 4926676Smckusick setsval(x.optr, y.optr->sval); 4936676Smckusick else if (y.optr->tval & NUM) 4946676Smckusick setfval(x.optr, y.optr->fval); 4956676Smckusick tempfree(y); 4966676Smckusick return(x); 4976676Smckusick } 4986676Smckusick xf = getfval(x.optr); 4996676Smckusick yf = getfval(y.optr); 5006676Smckusick switch (n) { 5016676Smckusick case ADDEQ: 5026676Smckusick xf += yf; 5036676Smckusick break; 5046676Smckusick case SUBEQ: 5056676Smckusick xf -= yf; 5066676Smckusick break; 5076676Smckusick case MULTEQ: 5086676Smckusick xf *= yf; 5096676Smckusick break; 5106676Smckusick case DIVEQ: 5116676Smckusick if (yf == 0) 5126676Smckusick error(FATAL, "division by zero"); 5136676Smckusick xf /= yf; 5146676Smckusick break; 5156676Smckusick case MODEQ: 5166676Smckusick if (yf == 0) 5176676Smckusick error(FATAL, "division by zero"); 5186676Smckusick xf = xf - yf*(long)(xf/yf); 5196676Smckusick break; 5206676Smckusick default: 5216676Smckusick error(FATAL, "illegal assignment operator %d", n); 5226676Smckusick break; 5236676Smckusick } 5246676Smckusick tempfree(y); 5256676Smckusick setfval(x.optr, xf); 5266676Smckusick return(x); 5276676Smckusick } 5286676Smckusick 5296676Smckusick obj cat(a,q) node **a; 5306676Smckusick { 5316676Smckusick obj x,y,z; 5326676Smckusick int n1, n2; 5336676Smckusick char *s; 5346676Smckusick 5356676Smckusick x = execute(a[0]); 5366676Smckusick y = execute(a[1]); 5376676Smckusick getsval(x.optr); 5386676Smckusick getsval(y.optr); 5396676Smckusick n1 = strlen(x.optr->sval); 5406676Smckusick n2 = strlen(y.optr->sval); 5416676Smckusick s = (char *) malloc(n1 + n2 + 1); 5426676Smckusick strcpy(s, x.optr->sval); 5436676Smckusick strcpy(s+n1, y.optr->sval); 5446676Smckusick tempfree(y); 5456676Smckusick z = gettemp(); 5466676Smckusick z.optr->sval = s; 5476676Smckusick z.optr->tval = STR; 5486676Smckusick tempfree(x); 5496676Smckusick return(z); 5506676Smckusick } 5516676Smckusick 5526676Smckusick obj pastat(a,n) node **a; 5536676Smckusick { 5546676Smckusick obj x; 5556676Smckusick 5566676Smckusick if (a[0]==nullstat) 5576676Smckusick x = true; 5586676Smckusick else 5596676Smckusick x = execute(a[0]); 5606676Smckusick if (istrue(x)) { 5616676Smckusick tempfree(x); 5626676Smckusick x = execute(a[1]); 5636676Smckusick } 5646676Smckusick return(x); 5656676Smckusick } 5666676Smckusick 5676676Smckusick obj dopa2(a,n) node **a; 5686676Smckusick { 5696676Smckusick obj x; 5706676Smckusick 5716676Smckusick if (pairstack[n]==0) { 5726676Smckusick x = execute(a[0]); 5736676Smckusick if (istrue(x)) 5746676Smckusick pairstack[n] = 1; 5756676Smckusick tempfree(x); 5766676Smckusick } 5776676Smckusick if (pairstack[n] == 1) { 5786676Smckusick x = execute(a[1]); 5796676Smckusick if (istrue(x)) 5806676Smckusick pairstack[n] = 0; 5816676Smckusick tempfree(x); 5826676Smckusick x = execute(a[2]); 5836676Smckusick return(x); 5846676Smckusick } 5856676Smckusick return(false); 5866676Smckusick } 5876676Smckusick 5886676Smckusick obj aprintf(a,n) node **a; 5896676Smckusick { 5906676Smckusick obj x; 5916676Smckusick 5926676Smckusick x = asprintf(a,n); 5936676Smckusick if (a[1]==NULL) { 5946676Smckusick printf("%s", x.optr->sval); 5956676Smckusick tempfree(x); 5966676Smckusick return(true); 5976676Smckusick } 5986676Smckusick redirprint(x.optr->sval, (int)a[1], a[2]); 5996676Smckusick return(x); 6006676Smckusick } 6016676Smckusick 6026676Smckusick obj split(a,nnn) node **a; 6036676Smckusick { 6046676Smckusick obj x; 6056676Smckusick cell *ap; 6066676Smckusick register char *s, *p; 6076676Smckusick char *t, temp, num[5]; 6086676Smckusick register int sep; 6096676Smckusick int n, flag; 6106676Smckusick 6116676Smckusick x = execute(a[0]); 6126676Smckusick s = getsval(x.optr); 6136676Smckusick tempfree(x); 6146676Smckusick if (a[2] == nullstat) 6156676Smckusick sep = **FS; 6166676Smckusick else { 6176676Smckusick x = execute(a[2]); 6186676Smckusick sep = getsval(x.optr)[0]; 6196676Smckusick tempfree(x); 6206676Smckusick } 6216676Smckusick ap = (cell *) a[1]; 6226676Smckusick freesymtab(ap); 6236676Smckusick dprintf("split: s=|%s|, a=%s, sep=|%c|\n", s, ap->nval, sep); 6246676Smckusick ap->tval &= ~STR; 6256676Smckusick ap->tval |= ARR; 6266676Smckusick ap->sval = (char *) makesymtab(); 6276676Smckusick 6286676Smckusick n = 0; 6296676Smckusick if (sep == ' ') 6306676Smckusick for (n = 0; ; ) { 6316676Smckusick while (*s == ' ' || *s == '\t' || *s == '\n') 6326676Smckusick s++; 6336676Smckusick if (*s == 0) 6346676Smckusick break; 6356676Smckusick n++; 6366676Smckusick t = s; 6376676Smckusick do 6386676Smckusick s++; 6396676Smckusick while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); 6406676Smckusick temp = *s; 6416676Smckusick *s = '\0'; 6426676Smckusick sprintf(num, "%d", n); 6436676Smckusick if (isnumber(t)) 6446676Smckusick setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval); 6456676Smckusick else 6466676Smckusick setsymtab(num, tostring(t), 0.0, STR, ap->sval); 6476676Smckusick *s = temp; 6486676Smckusick if (*s != 0) 6496676Smckusick s++; 6506676Smckusick } 6516676Smckusick else if (*s != 0) 6526676Smckusick for (;;) { 6536676Smckusick n++; 6546676Smckusick t = s; 6556676Smckusick while (*s != sep && *s != '\n' && *s != '\0') 6566676Smckusick s++; 6576676Smckusick temp = *s; 6586676Smckusick *s = '\0'; 6596676Smckusick sprintf(num, "%d", n); 6606676Smckusick if (isnumber(t)) 6616676Smckusick setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval); 6626676Smckusick else 6636676Smckusick setsymtab(num, tostring(t), 0.0, STR, ap->sval); 6646676Smckusick *s = temp; 6656676Smckusick if (*s++ == 0) 6666676Smckusick break; 6676676Smckusick } 6686676Smckusick x = gettemp(); 6696676Smckusick x.optr->tval = NUM; 6706676Smckusick x.optr->fval = n; 6716676Smckusick return(x); 6726676Smckusick } 6736676Smckusick 6746676Smckusick obj ifstat(a,n) node **a; 6756676Smckusick { 6766676Smckusick obj x; 6776676Smckusick 6786676Smckusick x = execute(a[0]); 6796676Smckusick if (istrue(x)) { 6806676Smckusick tempfree(x); 6816676Smckusick x = execute(a[1]); 6826676Smckusick } 6836676Smckusick else if (a[2] != nullstat) { 6846676Smckusick tempfree(x); 6856676Smckusick x = execute(a[2]); 6866676Smckusick } 6876676Smckusick return(x); 6886676Smckusick } 6896676Smckusick 6906676Smckusick obj whilestat(a,n) node **a; 6916676Smckusick { 6926676Smckusick obj x; 6936676Smckusick 6946676Smckusick for (;;) { 6956676Smckusick x = execute(a[0]); 6966676Smckusick if (!istrue(x)) return(x); 6976676Smckusick tempfree(x); 6986676Smckusick x = execute(a[1]); 6996676Smckusick if (isbreak(x)) { 7006676Smckusick x = true; 7016676Smckusick return(x); 7026676Smckusick } 7036676Smckusick if (isnext(x) || isexit(x)) 7046676Smckusick return(x); 7056676Smckusick tempfree(x); 7066676Smckusick } 7076676Smckusick } 7086676Smckusick 7096676Smckusick obj forstat(a,n) node **a; 7106676Smckusick { 7116676Smckusick obj x; 7126676Smckusick 7136676Smckusick tempfree(execute(a[0])); 7146676Smckusick for (;;) { 7156676Smckusick if (a[1]!=nullstat) { 7166676Smckusick x = execute(a[1]); 7176676Smckusick if (!istrue(x)) return(x); 7186676Smckusick else tempfree(x); 7196676Smckusick } 7206676Smckusick x = execute(a[3]); 7216676Smckusick if (isbreak(x)) { /* turn off break */ 7226676Smckusick x = true; 7236676Smckusick return(x); 7246676Smckusick } 7256676Smckusick if (isnext(x) || isexit(x)) 7266676Smckusick return(x); 7276676Smckusick tempfree(x); 7286676Smckusick tempfree(execute(a[2])); 7296676Smckusick } 7306676Smckusick } 7316676Smckusick 7326676Smckusick obj instat(a, n) node **a; 7336676Smckusick { 7346676Smckusick cell *vp, *arrayp, *cp, **tp; 7356676Smckusick obj x; 7366676Smckusick int i; 7376676Smckusick 7386676Smckusick vp = (cell *) a[0]; 7396676Smckusick arrayp = (cell *) a[1]; 7406676Smckusick if (!(arrayp->tval & ARR)) 7416676Smckusick error(FATAL, "%s is not an array", arrayp->nval); 7426676Smckusick tp = (cell **) arrayp->sval; 7436676Smckusick for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */ 7446676Smckusick for (cp = tp[i]; cp != NULL; cp = cp->nextval) { 7456676Smckusick setsval(vp, cp->nval); 7466676Smckusick x = execute(a[2]); 7476676Smckusick if (isbreak(x)) { 7486676Smckusick x = true; 7496676Smckusick return(x); 7506676Smckusick } 7516676Smckusick if (isnext(x) || isexit(x)) 7526676Smckusick return(x); 7536676Smckusick tempfree(x); 7546676Smckusick } 7556676Smckusick } 75613177Ssam return (true); 7576676Smckusick } 7586676Smckusick 7596676Smckusick obj jump(a,n) node **a; 7606676Smckusick { 7616676Smckusick obj x, y; 7626676Smckusick 7636676Smckusick x.otype = OJUMP; 7646676Smckusick switch (n) { 7656676Smckusick default: 7666676Smckusick error(FATAL, "illegal jump type %d", n); 7676676Smckusick break; 7686676Smckusick case EXIT: 7696676Smckusick if (a[0] != 0) { 7706676Smckusick y = execute(a[0]); 7716676Smckusick errorflag = getfval(y.optr); 7726676Smckusick } 7736676Smckusick x.osub = JEXIT; 7746676Smckusick break; 7756676Smckusick case NEXT: 7766676Smckusick x.osub = JNEXT; 7776676Smckusick break; 7786676Smckusick case BREAK: 7796676Smckusick x.osub = JBREAK; 7806676Smckusick break; 7816676Smckusick case CONTINUE: 7826676Smckusick x.osub = JCONT; 7836676Smckusick break; 7846676Smckusick } 7856676Smckusick return(x); 7866676Smckusick } 7876676Smckusick 7886676Smckusick obj fncn(a,n) node **a; 7896676Smckusick { 7906676Smckusick obj x; 7916676Smckusick awkfloat u; 7926676Smckusick int t; 7936676Smckusick 7946676Smckusick t = (int) a[0]; 7956676Smckusick x = execute(a[1]); 7966676Smckusick if (t == FLENGTH) 7976676Smckusick u = (awkfloat) strlen(getsval(x.optr)); 7986676Smckusick else if (t == FLOG) 7996676Smckusick u = log(getfval(x.optr)); 8006676Smckusick else if (t == FINT) 8016676Smckusick u = (awkfloat) (long) getfval(x.optr); 8026676Smckusick else if (t == FEXP) 8036676Smckusick u = exp(getfval(x.optr)); 8046676Smckusick else if (t == FSQRT) 8056676Smckusick u = sqrt(getfval(x.optr)); 8066676Smckusick else 8076676Smckusick error(FATAL, "illegal function type %d", t); 8086676Smckusick tempfree(x); 8096676Smckusick x = gettemp(); 8106676Smckusick setfval(x.optr, u); 8116676Smckusick return(x); 8126676Smckusick } 8136676Smckusick 8146676Smckusick obj print(a,n) node **a; 8156676Smckusick { 8166676Smckusick register node *x; 8176676Smckusick obj y; 8186676Smckusick char s[RECSIZE]; 8196676Smckusick 8206676Smckusick s[0] = '\0'; 8216676Smckusick for (x=a[0]; x!=NULL; x=x->nnext) { 8226676Smckusick y = execute(x); 8236676Smckusick strcat(s, getsval(y.optr)); 8246676Smckusick tempfree(y); 8256676Smckusick if (x->nnext==NULL) 8266676Smckusick strcat(s, *ORS); 8276676Smckusick else 8286676Smckusick strcat(s, *OFS); 8296676Smckusick } 8306676Smckusick if (strlen(s) >= RECSIZE) 8316676Smckusick error(FATAL, "string %.20s ... too long to print", s); 8326676Smckusick if (a[1]==nullstat) { 8336676Smckusick printf("%s", s); 8346676Smckusick return(true); 8356676Smckusick } 8366676Smckusick redirprint(s, (int)a[1], a[2]); 8376676Smckusick return(false); 8386676Smckusick } 8396676Smckusick 8406676Smckusick obj nullproc() {} 8416676Smckusick 8426676Smckusick obj nodetoobj(a) node *a; 8436676Smckusick { 8446676Smckusick obj x; 8456676Smckusick 8466676Smckusick x.optr = (cell *) a->nobj; 8476676Smckusick x.otype = OCELL; 8486676Smckusick x.osub = a->subtype; 8496676Smckusick if (isfld(x)) fldbld(); 8506676Smckusick return(x); 8516676Smckusick } 8526676Smckusick 8536676Smckusick redirprint(s, a, b) char *s; node *b; 8546676Smckusick { 8556676Smckusick register int i; 8566676Smckusick obj x; 8576676Smckusick 8586676Smckusick x = execute(b); 8596676Smckusick getsval(x.optr); 8606676Smckusick for (i=0; i<FILENUM; i++) 8616676Smckusick if (files[i].fp && strcmp(x.optr->sval, files[i].fname) == 0) 8626676Smckusick goto doit; 8636676Smckusick for (i=0; i<FILENUM; i++) 8646676Smckusick if (files[i].fp == 0) 8656676Smckusick break; 8666676Smckusick if (i >= FILENUM) 8676676Smckusick error(FATAL, "too many output files %d", i); 8686676Smckusick if (a == '|') /* a pipe! */ 8696676Smckusick files[i].fp = popen(x.optr->sval, "w"); 8706676Smckusick else if (a == APPEND) 8716676Smckusick files[i].fp = fopen(x.optr->sval, "a"); 8726676Smckusick else 8736676Smckusick files[i].fp = fopen(x.optr->sval, "w"); 8746676Smckusick if (files[i].fp == NULL) 8756676Smckusick error(FATAL, "can't open file %s", x.optr->sval); 8766676Smckusick files[i].fname = tostring(x.optr->sval); 877*17457Sralph files[i].type = a; 8786676Smckusick doit: 8796676Smckusick fprintf(files[i].fp, "%s", s); 8806676Smckusick #ifndef gcos 8816676Smckusick fflush(files[i].fp); /* in case someone is waiting for the output */ 8826676Smckusick #endif 8836676Smckusick tempfree(x); 8846676Smckusick } 885