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