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