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