1*6676Smckusick /* run.c 4.1 82/05/07 */ 2*6676Smckusick 3*6676Smckusick #include "awk.def" 4*6676Smckusick #include "math.h" 5*6676Smckusick #define RECSIZE 512 6*6676Smckusick #include "awk.h" 7*6676Smckusick #include "stdio.h" 8*6676Smckusick 9*6676Smckusick #define FILENUM 10 10*6676Smckusick struct 11*6676Smckusick { 12*6676Smckusick FILE *fp; 13*6676Smckusick char *fname; 14*6676Smckusick } files[FILENUM]; 15*6676Smckusick FILE *popen(); 16*6676Smckusick 17*6676Smckusick extern obj execute(), nodetoobj(), fieldel(), dopa2(), gettemp(); 18*6676Smckusick #define PA2NUM 29 19*6676Smckusick int pairstack[PA2NUM], paircnt; 20*6676Smckusick node *winner = (node *)NULL; 21*6676Smckusick #define MAXTMP 20 22*6676Smckusick cell tmps[MAXTMP]; 23*6676Smckusick static cell nullval ={0,0,0.0,NUM,0}; 24*6676Smckusick obj true ={ OBOOL, BTRUE, 0 }; 25*6676Smckusick obj false ={ OBOOL, BFALSE, 0 }; 26*6676Smckusick 27*6676Smckusick run() 28*6676Smckusick { 29*6676Smckusick execute(winner); 30*6676Smckusick } 31*6676Smckusick 32*6676Smckusick obj execute(u) node *u; 33*6676Smckusick { 34*6676Smckusick register obj (*proc)(); 35*6676Smckusick obj x; 36*6676Smckusick node *a; 37*6676Smckusick extern char *printname[]; 38*6676Smckusick 39*6676Smckusick if (u==(node *)NULL) 40*6676Smckusick return(true); 41*6676Smckusick for (a = u; ; a = a->nnext) { 42*6676Smckusick if (cantexec(a)) 43*6676Smckusick return(nodetoobj(a)); 44*6676Smckusick if (a->ntype==NPA2) 45*6676Smckusick proc=dopa2; 46*6676Smckusick else { 47*6676Smckusick if (notlegal(a->nobj)) 48*6676Smckusick error(FATAL, "illegal statement %o", a); 49*6676Smckusick proc = proctab[a->nobj-FIRSTTOKEN]; 50*6676Smckusick } 51*6676Smckusick x = (*proc)(a->narg,a->nobj); 52*6676Smckusick if (isfld(x)) fldbld(); 53*6676Smckusick if (isexpr(a)) 54*6676Smckusick return(x); 55*6676Smckusick /* a statement, goto next statement */ 56*6676Smckusick if (isjump(x)) 57*6676Smckusick return(x); 58*6676Smckusick if (a->nnext == (node *)NULL) 59*6676Smckusick return(x); 60*6676Smckusick tempfree(x); 61*6676Smckusick } 62*6676Smckusick } 63*6676Smckusick 64*6676Smckusick obj program(a, n) node **a; 65*6676Smckusick { 66*6676Smckusick obj x; 67*6676Smckusick 68*6676Smckusick if (a[0] != NULL) { 69*6676Smckusick x = execute(a[0]); 70*6676Smckusick if (isexit(x)) 71*6676Smckusick return(true); 72*6676Smckusick if (isjump(x)) 73*6676Smckusick error(FATAL, "unexpected break, continue or next"); 74*6676Smckusick tempfree(x); 75*6676Smckusick } 76*6676Smckusick while (getrec()) { 77*6676Smckusick x = execute(a[1]); 78*6676Smckusick if (isexit(x)) break; 79*6676Smckusick tempfree(x); 80*6676Smckusick } 81*6676Smckusick tempfree(x); 82*6676Smckusick if (a[2] != NULL) { 83*6676Smckusick x = execute(a[2]); 84*6676Smckusick if (isbreak(x) || isnext(x) || iscont(x)) 85*6676Smckusick error(FATAL, "unexpected break, continue or next"); 86*6676Smckusick tempfree(x); 87*6676Smckusick } 88*6676Smckusick return(true); 89*6676Smckusick } 90*6676Smckusick 91*6676Smckusick obj getline() 92*6676Smckusick { 93*6676Smckusick obj x; 94*6676Smckusick 95*6676Smckusick x = gettemp(); 96*6676Smckusick setfval(x.optr, (awkfloat) getrec()); 97*6676Smckusick return(x); 98*6676Smckusick } 99*6676Smckusick 100*6676Smckusick obj array(a,n) node **a; 101*6676Smckusick { 102*6676Smckusick obj x, y; 103*6676Smckusick extern obj arrayel(); 104*6676Smckusick 105*6676Smckusick x = execute(a[1]); 106*6676Smckusick y = arrayel(a[0], x); 107*6676Smckusick tempfree(x); 108*6676Smckusick return(y); 109*6676Smckusick } 110*6676Smckusick 111*6676Smckusick obj arrayel(a,b) node *a; obj b; 112*6676Smckusick { 113*6676Smckusick char *s; 114*6676Smckusick cell *x; 115*6676Smckusick int i; 116*6676Smckusick obj y; 117*6676Smckusick 118*6676Smckusick s = getsval(b.optr); 119*6676Smckusick x = (cell *) a; 120*6676Smckusick if (!(x->tval&ARR)) { 121*6676Smckusick xfree(x->sval); 122*6676Smckusick x->tval &= ~STR; 123*6676Smckusick x->tval |= ARR; 124*6676Smckusick x->sval = (char *) makesymtab(); 125*6676Smckusick } 126*6676Smckusick y.optr = setsymtab(s, tostring(""), 0.0, STR|NUM, x->sval); 127*6676Smckusick y.otype = OCELL; 128*6676Smckusick y.osub = CVAR; 129*6676Smckusick return(y); 130*6676Smckusick } 131*6676Smckusick 132*6676Smckusick obj matchop(a,n) node **a; 133*6676Smckusick { 134*6676Smckusick obj x; 135*6676Smckusick char *s; 136*6676Smckusick int i; 137*6676Smckusick 138*6676Smckusick x = execute(a[0]); 139*6676Smckusick if (isstr(x)) s = x.optr->sval; 140*6676Smckusick else s = getsval(x.optr); 141*6676Smckusick tempfree(x); 142*6676Smckusick i = match(a[1], s); 143*6676Smckusick if (n==MATCH && i==1 || n==NOTMATCH && i==0) 144*6676Smckusick return(true); 145*6676Smckusick else 146*6676Smckusick return(false); 147*6676Smckusick } 148*6676Smckusick 149*6676Smckusick obj boolop(a,n) node **a; 150*6676Smckusick { 151*6676Smckusick obj x, y; 152*6676Smckusick int i; 153*6676Smckusick 154*6676Smckusick x = execute(a[0]); 155*6676Smckusick i = istrue(x); 156*6676Smckusick tempfree(x); 157*6676Smckusick switch (n) { 158*6676Smckusick default: 159*6676Smckusick error(FATAL, "unknown boolean operator %d", n); 160*6676Smckusick case BOR: 161*6676Smckusick if (i) return(true); 162*6676Smckusick y = execute(a[1]); 163*6676Smckusick i = istrue(y); 164*6676Smckusick tempfree(y); 165*6676Smckusick if (i) return(true); 166*6676Smckusick else return(false); 167*6676Smckusick case AND: 168*6676Smckusick if ( !i ) return(false); 169*6676Smckusick y = execute(a[1]); 170*6676Smckusick i = istrue(y); 171*6676Smckusick tempfree(y); 172*6676Smckusick if (i) return(true); 173*6676Smckusick else return(false); 174*6676Smckusick case NOT: 175*6676Smckusick if (i) return(false); 176*6676Smckusick else return(true); 177*6676Smckusick } 178*6676Smckusick } 179*6676Smckusick 180*6676Smckusick obj relop(a,n) node **a; 181*6676Smckusick { 182*6676Smckusick int i; 183*6676Smckusick obj x, y; 184*6676Smckusick awkfloat j; 185*6676Smckusick 186*6676Smckusick x = execute(a[0]); 187*6676Smckusick y = execute(a[1]); 188*6676Smckusick if (x.optr->tval&NUM && y.optr->tval&NUM) { 189*6676Smckusick j = x.optr->fval - y.optr->fval; 190*6676Smckusick i = j<0? -1: (j>0? 1: 0); 191*6676Smckusick } else { 192*6676Smckusick i = strcmp(getsval(x.optr), getsval(y.optr)); 193*6676Smckusick } 194*6676Smckusick tempfree(x); 195*6676Smckusick tempfree(y); 196*6676Smckusick switch (n) { 197*6676Smckusick default: 198*6676Smckusick error(FATAL, "unknown relational operator %d", n); 199*6676Smckusick case LT: if (i<0) return(true); 200*6676Smckusick else return(false); 201*6676Smckusick case LE: if (i<=0) return(true); 202*6676Smckusick else return(false); 203*6676Smckusick case NE: if (i!=0) return(true); 204*6676Smckusick else return(false); 205*6676Smckusick case EQ: if (i==0) return(true); 206*6676Smckusick else return(false); 207*6676Smckusick case GE: if (i>=0) return(true); 208*6676Smckusick else return(false); 209*6676Smckusick case GT: if (i>0) return(true); 210*6676Smckusick else return(false); 211*6676Smckusick } 212*6676Smckusick } 213*6676Smckusick 214*6676Smckusick tempfree(a) obj a; 215*6676Smckusick { 216*6676Smckusick if (!istemp(a)) return; 217*6676Smckusick xfree(a.optr->sval); 218*6676Smckusick a.optr->tval = 0; 219*6676Smckusick } 220*6676Smckusick 221*6676Smckusick obj gettemp() 222*6676Smckusick { 223*6676Smckusick int i; 224*6676Smckusick obj x; 225*6676Smckusick 226*6676Smckusick for (i=0; i<MAXTMP; i++) 227*6676Smckusick if (tmps[i].tval==0) 228*6676Smckusick break; 229*6676Smckusick if (i==MAXTMP) 230*6676Smckusick error(FATAL, "out of temporaries in gettemp"); 231*6676Smckusick x.optr = &tmps[i]; 232*6676Smckusick tmps[i] = nullval; 233*6676Smckusick x.otype = OCELL; 234*6676Smckusick x.osub = CTEMP; 235*6676Smckusick return(x); 236*6676Smckusick } 237*6676Smckusick 238*6676Smckusick obj indirect(a,n) node **a; 239*6676Smckusick { 240*6676Smckusick obj x; 241*6676Smckusick int m; 242*6676Smckusick cell *fieldadr(); 243*6676Smckusick 244*6676Smckusick x = execute(a[0]); 245*6676Smckusick m = getfval(x.optr); 246*6676Smckusick tempfree(x); 247*6676Smckusick x.optr = fieldadr(m); 248*6676Smckusick x.otype = OCELL; 249*6676Smckusick x.osub = CFLD; 250*6676Smckusick return(x); 251*6676Smckusick } 252*6676Smckusick 253*6676Smckusick obj substr(a, nnn) node **a; 254*6676Smckusick { 255*6676Smckusick char *s, temp; 256*6676Smckusick obj x; 257*6676Smckusick int k, m, n; 258*6676Smckusick 259*6676Smckusick x = execute(a[0]); 260*6676Smckusick s = getsval(x.optr); 261*6676Smckusick k = strlen(s) + 1; 262*6676Smckusick tempfree(x); 263*6676Smckusick x = execute(a[1]); 264*6676Smckusick m = getfval(x.optr); 265*6676Smckusick if (m <= 0) 266*6676Smckusick m = 1; 267*6676Smckusick else if (m > k) 268*6676Smckusick m = k; 269*6676Smckusick tempfree(x); 270*6676Smckusick if (a[2] != nullstat) { 271*6676Smckusick x = execute(a[2]); 272*6676Smckusick n = getfval(x.optr); 273*6676Smckusick tempfree(x); 274*6676Smckusick } 275*6676Smckusick else 276*6676Smckusick n = k - 1; 277*6676Smckusick if (n < 0) 278*6676Smckusick n = 0; 279*6676Smckusick else if (n > k - m) 280*6676Smckusick n = k - m; 281*6676Smckusick dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s); 282*6676Smckusick x = gettemp(); 283*6676Smckusick temp = s[n+m-1]; /* with thanks to John Linderman */ 284*6676Smckusick s[n+m-1] = '\0'; 285*6676Smckusick setsval(x.optr, s + m - 1); 286*6676Smckusick s[n+m-1] = temp; 287*6676Smckusick return(x); 288*6676Smckusick } 289*6676Smckusick 290*6676Smckusick obj sindex(a, nnn) node **a; 291*6676Smckusick { 292*6676Smckusick obj x; 293*6676Smckusick char *s1, *s2, *p1, *p2, *q; 294*6676Smckusick 295*6676Smckusick x = execute(a[0]); 296*6676Smckusick s1 = getsval(x.optr); 297*6676Smckusick tempfree(x); 298*6676Smckusick x = execute(a[1]); 299*6676Smckusick s2 = getsval(x.optr); 300*6676Smckusick tempfree(x); 301*6676Smckusick 302*6676Smckusick x = gettemp(); 303*6676Smckusick for (p1 = s1; *p1 != '\0'; p1++) { 304*6676Smckusick for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) 305*6676Smckusick ; 306*6676Smckusick if (*p2 == '\0') { 307*6676Smckusick setfval(x.optr, (awkfloat) (p1 - s1 + 1)); /* origin 1 */ 308*6676Smckusick return(x); 309*6676Smckusick } 310*6676Smckusick } 311*6676Smckusick setfval(x.optr, 0.0); 312*6676Smckusick return(x); 313*6676Smckusick } 314*6676Smckusick 315*6676Smckusick char *format(s,a) char *s; node *a; 316*6676Smckusick { 317*6676Smckusick char *buf, *p, fmt[200], *t, *os; 318*6676Smckusick obj x; 319*6676Smckusick int flag = 0; 320*6676Smckusick awkfloat xf; 321*6676Smckusick 322*6676Smckusick os = s; 323*6676Smckusick p = buf = (char *)malloc(RECSIZE); 324*6676Smckusick while (*s) { 325*6676Smckusick if (*s != '%') { 326*6676Smckusick *p++ = *s++; 327*6676Smckusick continue; 328*6676Smckusick } 329*6676Smckusick if (*(s+1) == '%') { 330*6676Smckusick *p++ = '%'; 331*6676Smckusick s += 2; 332*6676Smckusick continue; 333*6676Smckusick } 334*6676Smckusick for (t=fmt; (*t++ = *s) != '\0'; s++) 335*6676Smckusick if (*s >= 'a' && *s <= 'z' && *s != 'l') 336*6676Smckusick break; 337*6676Smckusick *t = '\0'; 338*6676Smckusick if (t >= fmt + sizeof(fmt)) 339*6676Smckusick error(FATAL, "format item %.20s... too long", os); 340*6676Smckusick switch (*s) { 341*6676Smckusick case 'f': case 'e': case 'g': 342*6676Smckusick flag = 1; 343*6676Smckusick break; 344*6676Smckusick case 'd': 345*6676Smckusick flag = 2; 346*6676Smckusick if(*(s-1) == 'l') break; 347*6676Smckusick *(t-1) = 'l'; 348*6676Smckusick *t = 'd'; 349*6676Smckusick *++t = '\0'; 350*6676Smckusick break; 351*6676Smckusick case 'o': case 'x': 352*6676Smckusick flag = *(s-1)=='l' ? 2 : 3; 353*6676Smckusick break; 354*6676Smckusick case 'c': 355*6676Smckusick flag = 3; 356*6676Smckusick break; 357*6676Smckusick case 's': 358*6676Smckusick flag = 4; 359*6676Smckusick break; 360*6676Smckusick default: 361*6676Smckusick flag = 0; 362*6676Smckusick break; 363*6676Smckusick } 364*6676Smckusick if (flag == 0) { 365*6676Smckusick sprintf(p, "%s", fmt); 366*6676Smckusick p += strlen(p); 367*6676Smckusick continue; 368*6676Smckusick } 369*6676Smckusick if (a == NULL) 370*6676Smckusick error(FATAL, "not enough arguments in printf(%s)", os); 371*6676Smckusick x = execute(a); 372*6676Smckusick a = a->nnext; 373*6676Smckusick if (flag != 4) /* watch out for converting to numbers! */ 374*6676Smckusick xf = getfval(x.optr); 375*6676Smckusick if (flag==1) sprintf(p, fmt, xf); 376*6676Smckusick else if (flag==2) sprintf(p, fmt, (long)xf); 377*6676Smckusick else if (flag==3) sprintf(p, fmt, (int)xf); 378*6676Smckusick else if (flag==4) sprintf(p, fmt, x.optr->sval==NULL ? "" : getsval(x.optr)); 379*6676Smckusick tempfree(x); 380*6676Smckusick p += strlen(p); 381*6676Smckusick s++; 382*6676Smckusick } 383*6676Smckusick *p = '\0'; 384*6676Smckusick return(buf); 385*6676Smckusick } 386*6676Smckusick 387*6676Smckusick obj asprintf(a,n) node **a; 388*6676Smckusick { 389*6676Smckusick obj x; 390*6676Smckusick node *y; 391*6676Smckusick char *s; 392*6676Smckusick 393*6676Smckusick y = a[0]->nnext; 394*6676Smckusick x = execute(a[0]); 395*6676Smckusick s = format(getsval(x.optr), y); 396*6676Smckusick tempfree(x); 397*6676Smckusick x = gettemp(); 398*6676Smckusick x.optr->sval = s; 399*6676Smckusick x.optr->tval = STR; 400*6676Smckusick return(x); 401*6676Smckusick } 402*6676Smckusick 403*6676Smckusick obj arith(a,n) node **a; 404*6676Smckusick { 405*6676Smckusick awkfloat i,j; 406*6676Smckusick obj x,y,z; 407*6676Smckusick 408*6676Smckusick x = execute(a[0]); 409*6676Smckusick i = getfval(x.optr); 410*6676Smckusick tempfree(x); 411*6676Smckusick if (n != UMINUS) { 412*6676Smckusick y = execute(a[1]); 413*6676Smckusick j = getfval(y.optr); 414*6676Smckusick tempfree(y); 415*6676Smckusick } 416*6676Smckusick z = gettemp(); 417*6676Smckusick switch (n) { 418*6676Smckusick default: 419*6676Smckusick error(FATAL, "illegal arithmetic operator %d", n); 420*6676Smckusick case ADD: 421*6676Smckusick i += j; 422*6676Smckusick break; 423*6676Smckusick case MINUS: 424*6676Smckusick i -= j; 425*6676Smckusick break; 426*6676Smckusick case MULT: 427*6676Smckusick i *= j; 428*6676Smckusick break; 429*6676Smckusick case DIVIDE: 430*6676Smckusick if (j == 0) 431*6676Smckusick error(FATAL, "division by zero"); 432*6676Smckusick i /= j; 433*6676Smckusick break; 434*6676Smckusick case MOD: 435*6676Smckusick if (j == 0) 436*6676Smckusick error(FATAL, "division by zero"); 437*6676Smckusick i = i - j*(long)(i/j); 438*6676Smckusick break; 439*6676Smckusick case UMINUS: 440*6676Smckusick i = -i; 441*6676Smckusick break; 442*6676Smckusick } 443*6676Smckusick setfval(z.optr, i); 444*6676Smckusick return(z); 445*6676Smckusick } 446*6676Smckusick 447*6676Smckusick obj incrdecr(a, n) node **a; 448*6676Smckusick { 449*6676Smckusick obj x, z; 450*6676Smckusick int k; 451*6676Smckusick awkfloat xf; 452*6676Smckusick 453*6676Smckusick x = execute(a[0]); 454*6676Smckusick xf = getfval(x.optr); 455*6676Smckusick k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 456*6676Smckusick if (n == PREINCR || n == PREDECR) { 457*6676Smckusick setfval(x.optr, xf + k); 458*6676Smckusick return(x); 459*6676Smckusick } 460*6676Smckusick z = gettemp(); 461*6676Smckusick setfval(z.optr, xf); 462*6676Smckusick setfval(x.optr, xf + k); 463*6676Smckusick tempfree(x); 464*6676Smckusick return(z); 465*6676Smckusick } 466*6676Smckusick 467*6676Smckusick 468*6676Smckusick obj assign(a,n) node **a; 469*6676Smckusick { 470*6676Smckusick obj x, y; 471*6676Smckusick awkfloat xf, yf; 472*6676Smckusick 473*6676Smckusick x = execute(a[0]); 474*6676Smckusick y = execute(a[1]); 475*6676Smckusick if (n == ASSIGN) { /* ordinary assignment */ 476*6676Smckusick if ((y.optr->tval & (STR|NUM)) == (STR|NUM)) { 477*6676Smckusick setsval(x.optr, y.optr->sval); 478*6676Smckusick x.optr->fval = y.optr->fval; 479*6676Smckusick x.optr->tval |= NUM; 480*6676Smckusick } 481*6676Smckusick else if (y.optr->tval & STR) 482*6676Smckusick setsval(x.optr, y.optr->sval); 483*6676Smckusick else if (y.optr->tval & NUM) 484*6676Smckusick setfval(x.optr, y.optr->fval); 485*6676Smckusick tempfree(y); 486*6676Smckusick return(x); 487*6676Smckusick } 488*6676Smckusick xf = getfval(x.optr); 489*6676Smckusick yf = getfval(y.optr); 490*6676Smckusick switch (n) { 491*6676Smckusick case ADDEQ: 492*6676Smckusick xf += yf; 493*6676Smckusick break; 494*6676Smckusick case SUBEQ: 495*6676Smckusick xf -= yf; 496*6676Smckusick break; 497*6676Smckusick case MULTEQ: 498*6676Smckusick xf *= yf; 499*6676Smckusick break; 500*6676Smckusick case DIVEQ: 501*6676Smckusick if (yf == 0) 502*6676Smckusick error(FATAL, "division by zero"); 503*6676Smckusick xf /= yf; 504*6676Smckusick break; 505*6676Smckusick case MODEQ: 506*6676Smckusick if (yf == 0) 507*6676Smckusick error(FATAL, "division by zero"); 508*6676Smckusick xf = xf - yf*(long)(xf/yf); 509*6676Smckusick break; 510*6676Smckusick default: 511*6676Smckusick error(FATAL, "illegal assignment operator %d", n); 512*6676Smckusick break; 513*6676Smckusick } 514*6676Smckusick tempfree(y); 515*6676Smckusick setfval(x.optr, xf); 516*6676Smckusick return(x); 517*6676Smckusick } 518*6676Smckusick 519*6676Smckusick obj cat(a,q) node **a; 520*6676Smckusick { 521*6676Smckusick obj x,y,z; 522*6676Smckusick int n1, n2; 523*6676Smckusick char *s; 524*6676Smckusick 525*6676Smckusick x = execute(a[0]); 526*6676Smckusick y = execute(a[1]); 527*6676Smckusick getsval(x.optr); 528*6676Smckusick getsval(y.optr); 529*6676Smckusick n1 = strlen(x.optr->sval); 530*6676Smckusick n2 = strlen(y.optr->sval); 531*6676Smckusick s = (char *) malloc(n1 + n2 + 1); 532*6676Smckusick strcpy(s, x.optr->sval); 533*6676Smckusick strcpy(s+n1, y.optr->sval); 534*6676Smckusick tempfree(y); 535*6676Smckusick z = gettemp(); 536*6676Smckusick z.optr->sval = s; 537*6676Smckusick z.optr->tval = STR; 538*6676Smckusick tempfree(x); 539*6676Smckusick return(z); 540*6676Smckusick } 541*6676Smckusick 542*6676Smckusick obj pastat(a,n) node **a; 543*6676Smckusick { 544*6676Smckusick obj x; 545*6676Smckusick 546*6676Smckusick if (a[0]==nullstat) 547*6676Smckusick x = true; 548*6676Smckusick else 549*6676Smckusick x = execute(a[0]); 550*6676Smckusick if (istrue(x)) { 551*6676Smckusick tempfree(x); 552*6676Smckusick x = execute(a[1]); 553*6676Smckusick } 554*6676Smckusick return(x); 555*6676Smckusick } 556*6676Smckusick 557*6676Smckusick obj dopa2(a,n) node **a; 558*6676Smckusick { 559*6676Smckusick obj x; 560*6676Smckusick 561*6676Smckusick if (pairstack[n]==0) { 562*6676Smckusick x = execute(a[0]); 563*6676Smckusick if (istrue(x)) 564*6676Smckusick pairstack[n] = 1; 565*6676Smckusick tempfree(x); 566*6676Smckusick } 567*6676Smckusick if (pairstack[n] == 1) { 568*6676Smckusick x = execute(a[1]); 569*6676Smckusick if (istrue(x)) 570*6676Smckusick pairstack[n] = 0; 571*6676Smckusick tempfree(x); 572*6676Smckusick x = execute(a[2]); 573*6676Smckusick return(x); 574*6676Smckusick } 575*6676Smckusick return(false); 576*6676Smckusick } 577*6676Smckusick 578*6676Smckusick obj aprintf(a,n) node **a; 579*6676Smckusick { 580*6676Smckusick obj x; 581*6676Smckusick 582*6676Smckusick x = asprintf(a,n); 583*6676Smckusick if (a[1]==NULL) { 584*6676Smckusick printf("%s", x.optr->sval); 585*6676Smckusick tempfree(x); 586*6676Smckusick return(true); 587*6676Smckusick } 588*6676Smckusick redirprint(x.optr->sval, (int)a[1], a[2]); 589*6676Smckusick return(x); 590*6676Smckusick } 591*6676Smckusick 592*6676Smckusick obj split(a,nnn) node **a; 593*6676Smckusick { 594*6676Smckusick obj x; 595*6676Smckusick cell *ap; 596*6676Smckusick register char *s, *p; 597*6676Smckusick char *t, temp, num[5]; 598*6676Smckusick register int sep; 599*6676Smckusick int n, flag; 600*6676Smckusick 601*6676Smckusick x = execute(a[0]); 602*6676Smckusick s = getsval(x.optr); 603*6676Smckusick tempfree(x); 604*6676Smckusick if (a[2] == nullstat) 605*6676Smckusick sep = **FS; 606*6676Smckusick else { 607*6676Smckusick x = execute(a[2]); 608*6676Smckusick sep = getsval(x.optr)[0]; 609*6676Smckusick tempfree(x); 610*6676Smckusick } 611*6676Smckusick ap = (cell *) a[1]; 612*6676Smckusick freesymtab(ap); 613*6676Smckusick dprintf("split: s=|%s|, a=%s, sep=|%c|\n", s, ap->nval, sep); 614*6676Smckusick ap->tval &= ~STR; 615*6676Smckusick ap->tval |= ARR; 616*6676Smckusick ap->sval = (char *) makesymtab(); 617*6676Smckusick 618*6676Smckusick n = 0; 619*6676Smckusick if (sep == ' ') 620*6676Smckusick for (n = 0; ; ) { 621*6676Smckusick while (*s == ' ' || *s == '\t' || *s == '\n') 622*6676Smckusick s++; 623*6676Smckusick if (*s == 0) 624*6676Smckusick break; 625*6676Smckusick n++; 626*6676Smckusick t = s; 627*6676Smckusick do 628*6676Smckusick s++; 629*6676Smckusick while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); 630*6676Smckusick temp = *s; 631*6676Smckusick *s = '\0'; 632*6676Smckusick sprintf(num, "%d", n); 633*6676Smckusick if (isnumber(t)) 634*6676Smckusick setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval); 635*6676Smckusick else 636*6676Smckusick setsymtab(num, tostring(t), 0.0, STR, ap->sval); 637*6676Smckusick *s = temp; 638*6676Smckusick if (*s != 0) 639*6676Smckusick s++; 640*6676Smckusick } 641*6676Smckusick else if (*s != 0) 642*6676Smckusick for (;;) { 643*6676Smckusick n++; 644*6676Smckusick t = s; 645*6676Smckusick while (*s != sep && *s != '\n' && *s != '\0') 646*6676Smckusick s++; 647*6676Smckusick temp = *s; 648*6676Smckusick *s = '\0'; 649*6676Smckusick sprintf(num, "%d", n); 650*6676Smckusick if (isnumber(t)) 651*6676Smckusick setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval); 652*6676Smckusick else 653*6676Smckusick setsymtab(num, tostring(t), 0.0, STR, ap->sval); 654*6676Smckusick *s = temp; 655*6676Smckusick if (*s++ == 0) 656*6676Smckusick break; 657*6676Smckusick } 658*6676Smckusick x = gettemp(); 659*6676Smckusick x.optr->tval = NUM; 660*6676Smckusick x.optr->fval = n; 661*6676Smckusick return(x); 662*6676Smckusick } 663*6676Smckusick 664*6676Smckusick obj ifstat(a,n) node **a; 665*6676Smckusick { 666*6676Smckusick obj x; 667*6676Smckusick 668*6676Smckusick x = execute(a[0]); 669*6676Smckusick if (istrue(x)) { 670*6676Smckusick tempfree(x); 671*6676Smckusick x = execute(a[1]); 672*6676Smckusick } 673*6676Smckusick else if (a[2] != nullstat) { 674*6676Smckusick tempfree(x); 675*6676Smckusick x = execute(a[2]); 676*6676Smckusick } 677*6676Smckusick return(x); 678*6676Smckusick } 679*6676Smckusick 680*6676Smckusick obj whilestat(a,n) node **a; 681*6676Smckusick { 682*6676Smckusick obj x; 683*6676Smckusick 684*6676Smckusick for (;;) { 685*6676Smckusick x = execute(a[0]); 686*6676Smckusick if (!istrue(x)) return(x); 687*6676Smckusick tempfree(x); 688*6676Smckusick x = execute(a[1]); 689*6676Smckusick if (isbreak(x)) { 690*6676Smckusick x = true; 691*6676Smckusick return(x); 692*6676Smckusick } 693*6676Smckusick if (isnext(x) || isexit(x)) 694*6676Smckusick return(x); 695*6676Smckusick tempfree(x); 696*6676Smckusick } 697*6676Smckusick } 698*6676Smckusick 699*6676Smckusick obj forstat(a,n) node **a; 700*6676Smckusick { 701*6676Smckusick obj x; 702*6676Smckusick 703*6676Smckusick tempfree(execute(a[0])); 704*6676Smckusick for (;;) { 705*6676Smckusick if (a[1]!=nullstat) { 706*6676Smckusick x = execute(a[1]); 707*6676Smckusick if (!istrue(x)) return(x); 708*6676Smckusick else tempfree(x); 709*6676Smckusick } 710*6676Smckusick x = execute(a[3]); 711*6676Smckusick if (isbreak(x)) { /* turn off break */ 712*6676Smckusick x = true; 713*6676Smckusick return(x); 714*6676Smckusick } 715*6676Smckusick if (isnext(x) || isexit(x)) 716*6676Smckusick return(x); 717*6676Smckusick tempfree(x); 718*6676Smckusick tempfree(execute(a[2])); 719*6676Smckusick } 720*6676Smckusick } 721*6676Smckusick 722*6676Smckusick obj instat(a, n) node **a; 723*6676Smckusick { 724*6676Smckusick cell *vp, *arrayp, *cp, **tp; 725*6676Smckusick obj x; 726*6676Smckusick int i; 727*6676Smckusick 728*6676Smckusick vp = (cell *) a[0]; 729*6676Smckusick arrayp = (cell *) a[1]; 730*6676Smckusick if (!(arrayp->tval & ARR)) 731*6676Smckusick error(FATAL, "%s is not an array", arrayp->nval); 732*6676Smckusick tp = (cell **) arrayp->sval; 733*6676Smckusick for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */ 734*6676Smckusick for (cp = tp[i]; cp != NULL; cp = cp->nextval) { 735*6676Smckusick setsval(vp, cp->nval); 736*6676Smckusick x = execute(a[2]); 737*6676Smckusick if (isbreak(x)) { 738*6676Smckusick x = true; 739*6676Smckusick return(x); 740*6676Smckusick } 741*6676Smckusick if (isnext(x) || isexit(x)) 742*6676Smckusick return(x); 743*6676Smckusick tempfree(x); 744*6676Smckusick } 745*6676Smckusick } 746*6676Smckusick } 747*6676Smckusick 748*6676Smckusick obj jump(a,n) node **a; 749*6676Smckusick { 750*6676Smckusick obj x, y; 751*6676Smckusick 752*6676Smckusick x.otype = OJUMP; 753*6676Smckusick switch (n) { 754*6676Smckusick default: 755*6676Smckusick error(FATAL, "illegal jump type %d", n); 756*6676Smckusick break; 757*6676Smckusick case EXIT: 758*6676Smckusick if (a[0] != 0) { 759*6676Smckusick y = execute(a[0]); 760*6676Smckusick errorflag = getfval(y.optr); 761*6676Smckusick } 762*6676Smckusick x.osub = JEXIT; 763*6676Smckusick break; 764*6676Smckusick case NEXT: 765*6676Smckusick x.osub = JNEXT; 766*6676Smckusick break; 767*6676Smckusick case BREAK: 768*6676Smckusick x.osub = JBREAK; 769*6676Smckusick break; 770*6676Smckusick case CONTINUE: 771*6676Smckusick x.osub = JCONT; 772*6676Smckusick break; 773*6676Smckusick } 774*6676Smckusick return(x); 775*6676Smckusick } 776*6676Smckusick 777*6676Smckusick obj fncn(a,n) node **a; 778*6676Smckusick { 779*6676Smckusick obj x; 780*6676Smckusick awkfloat u; 781*6676Smckusick int t; 782*6676Smckusick 783*6676Smckusick t = (int) a[0]; 784*6676Smckusick x = execute(a[1]); 785*6676Smckusick if (t == FLENGTH) 786*6676Smckusick u = (awkfloat) strlen(getsval(x.optr)); 787*6676Smckusick else if (t == FLOG) 788*6676Smckusick u = log(getfval(x.optr)); 789*6676Smckusick else if (t == FINT) 790*6676Smckusick u = (awkfloat) (long) getfval(x.optr); 791*6676Smckusick else if (t == FEXP) 792*6676Smckusick u = exp(getfval(x.optr)); 793*6676Smckusick else if (t == FSQRT) 794*6676Smckusick u = sqrt(getfval(x.optr)); 795*6676Smckusick else 796*6676Smckusick error(FATAL, "illegal function type %d", t); 797*6676Smckusick tempfree(x); 798*6676Smckusick x = gettemp(); 799*6676Smckusick setfval(x.optr, u); 800*6676Smckusick return(x); 801*6676Smckusick } 802*6676Smckusick 803*6676Smckusick obj print(a,n) node **a; 804*6676Smckusick { 805*6676Smckusick register node *x; 806*6676Smckusick obj y; 807*6676Smckusick char s[RECSIZE]; 808*6676Smckusick 809*6676Smckusick s[0] = '\0'; 810*6676Smckusick for (x=a[0]; x!=NULL; x=x->nnext) { 811*6676Smckusick y = execute(x); 812*6676Smckusick strcat(s, getsval(y.optr)); 813*6676Smckusick tempfree(y); 814*6676Smckusick if (x->nnext==NULL) 815*6676Smckusick strcat(s, *ORS); 816*6676Smckusick else 817*6676Smckusick strcat(s, *OFS); 818*6676Smckusick } 819*6676Smckusick if (strlen(s) >= RECSIZE) 820*6676Smckusick error(FATAL, "string %.20s ... too long to print", s); 821*6676Smckusick if (a[1]==nullstat) { 822*6676Smckusick printf("%s", s); 823*6676Smckusick return(true); 824*6676Smckusick } 825*6676Smckusick redirprint(s, (int)a[1], a[2]); 826*6676Smckusick return(false); 827*6676Smckusick } 828*6676Smckusick 829*6676Smckusick obj nullproc() {} 830*6676Smckusick 831*6676Smckusick obj nodetoobj(a) node *a; 832*6676Smckusick { 833*6676Smckusick obj x; 834*6676Smckusick 835*6676Smckusick x.optr = (cell *) a->nobj; 836*6676Smckusick x.otype = OCELL; 837*6676Smckusick x.osub = a->subtype; 838*6676Smckusick if (isfld(x)) fldbld(); 839*6676Smckusick return(x); 840*6676Smckusick } 841*6676Smckusick 842*6676Smckusick redirprint(s, a, b) char *s; node *b; 843*6676Smckusick { 844*6676Smckusick register int i; 845*6676Smckusick obj x; 846*6676Smckusick 847*6676Smckusick x = execute(b); 848*6676Smckusick getsval(x.optr); 849*6676Smckusick for (i=0; i<FILENUM; i++) 850*6676Smckusick if (files[i].fp && strcmp(x.optr->sval, files[i].fname) == 0) 851*6676Smckusick goto doit; 852*6676Smckusick for (i=0; i<FILENUM; i++) 853*6676Smckusick if (files[i].fp == 0) 854*6676Smckusick break; 855*6676Smckusick if (i >= FILENUM) 856*6676Smckusick error(FATAL, "too many output files %d", i); 857*6676Smckusick if (a == '|') /* a pipe! */ 858*6676Smckusick files[i].fp = popen(x.optr->sval, "w"); 859*6676Smckusick else if (a == APPEND) 860*6676Smckusick files[i].fp = fopen(x.optr->sval, "a"); 861*6676Smckusick else 862*6676Smckusick files[i].fp = fopen(x.optr->sval, "w"); 863*6676Smckusick if (files[i].fp == NULL) 864*6676Smckusick error(FATAL, "can't open file %s", x.optr->sval); 865*6676Smckusick files[i].fname = tostring(x.optr->sval); 866*6676Smckusick doit: 867*6676Smckusick fprintf(files[i].fp, "%s", s); 868*6676Smckusick #ifndef gcos 869*6676Smckusick fflush(files[i].fp); /* in case someone is waiting for the output */ 870*6676Smckusick #endif 871*6676Smckusick tempfree(x); 872*6676Smckusick } 873