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

Defined functions

aprintf defined in line 588; never used
arith defined in line 413; never used
array defined in line 110; never used
arrayel defined in line 121; used 2 times
asprintf defined in line 397; used 1 times
assign defined in line 478; never used
boolop defined in line 159; never used
cat defined in line 529; never used
dopa2 defined in line 567; used 2 times
execute defined in line 42; used 48 times
fncn defined in line 788; never used
format defined in line 325; used 1 times
forstat defined in line 709; never used
getline defined in line 101; never used
gettemp defined in line 231; used 10 times
ifstat defined in line 674; never used
incrdecr defined in line 457; never used
indirect defined in line 248; never used
instat defined in line 732; never used
jump defined in line 759; never used
matchop defined in line 142; never used
nodetoobj defined in line 842; used 2 times
nullproc defined in line 840; used 1 times
pastat defined in line 552; never used
print defined in line 814; never used
program defined in line 74; never used
redirprint defined in line 853; used 2 times
relop defined in line 190; used 1 times
run defined in line 30; used 1 times
sindex defined in line 300; never used
split defined in line 602; never used
substr defined in line 263; never used
tempfree defined in line 224; used 45 times
whilestat defined in line 690; never used

Defined variables

nullval defined in line 26; used 1 times
paircnt defined in line 22; never used
pairstack defined in line 22; used 4 times
sccsid defined in line 2; never used
tmps defined in line 25; used 3 times
winner defined in line 23; used 3 times

Defined macros

FILENUM defined in line 11; used 5 times
MAXTMP defined in line 24; used 3 times
PA2NUM defined in line 21; used 1 times
  • in line 22
RECSIZE defined in line 9; used 3 times
Last modified: 1987-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1695
Valid CSS Valid XHTML 1.0 Strict