148236Sbostic /*-
248236Sbostic * Copyright (c) 1991 The Regents of the University of California.
348236Sbostic * All rights reserved.
448236Sbostic *
548236Sbostic * %sccs.include.proprietary.c%
648236Sbostic */
748236Sbostic
814474Ssam #ifndef lint
9*60482Sbostic static char sccsid[] = "@(#)run.c 4.10 (Berkeley) 05/26/93";
1048236Sbostic #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
run()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
execute(u)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
program(a,n)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
getline()1106676Smckusick obj getline()
1116676Smckusick {
1126676Smckusick obj x;
1136676Smckusick
1146676Smckusick x = gettemp();
1156676Smckusick setfval(x.optr, (awkfloat) getrec());
1166676Smckusick return(x);
1176676Smckusick }
1186676Smckusick
array(a,n)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
arrayel(a,b)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
matchop(a,n)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
boolop(a,n)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
relop(a,n)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
tempfree(a)2336676Smckusick tempfree(a) obj a;
2346676Smckusick {
2356676Smckusick if (!istemp(a)) return;
23610794Ssam strfree(a.optr->sval);
2376676Smckusick a.optr->tval = 0;
2386676Smckusick }
2396676Smckusick
gettemp()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
indirect(a,n)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
substr(a,nnn)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
sindex(a,nnn)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
format(s,a)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
asprintf(a,n)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
arith(a,n)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
incrdecr(a,n)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
assign(a,n)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
cat(a,q)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
pastat(a,n)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
dopa2(a,n)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
aprintf(a,n)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
split(a,nnn)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);
652*60482Sbostic if (isanumber(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);
669*60482Sbostic if (isanumber(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
ifstat(a,n)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
whilestat(a,n)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
forstat(a,n)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
instat(a,n)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
jump(a,n)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
fncn(a,n)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
print(a,n)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
nullproc()8496676Smckusick obj nullproc() {}
8506676Smckusick
nodetoobj(a)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
redirprint(s,a,b)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