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