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