1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 27 28 29 /* 30 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 31 * Use is subject to license terms. 32 */ 33 34 35 #ident "%Z%%M% %I% %E% SMI" 36 #define DEBUG 37 #define tempfree(a) {if (istemp(a)) {xfree(a->sval); a->tval = 0; }} 38 39 #include "awk.def" 40 #include "math.h" 41 #include "awk.h" 42 #include "stdio.h" 43 #include "ctype.h" 44 #include "wctype.h" 45 #include "awktype.h" 46 #include <stdlib.h> 47 48 #define RECSIZE BUFSIZ 49 50 #define FILENUM 10 51 struct 52 { 53 FILE *fp; 54 int type; 55 wchar_t *fname; 56 } files[FILENUM]; 57 FILE *popen(); 58 59 extern CELL *execute(), *nodetoobj(), *fieldel(), *dopa2(), *gettemp(); 60 61 #define PA2NUM 29 62 int pairstack[PA2NUM], paircnt; 63 NODE *winner = NULL; 64 #define MAXTMP 20 65 CELL tmps[MAXTMP]; 66 67 static CELL truecell ={ OBOOL, BTRUE, 0, 0, 0.0, NUM, 0 }; 68 CELL *true = &truecell; 69 static CELL falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM, 0 }; 70 CELL *false = &falsecell; 71 static CELL breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM, 0 }; 72 CELL *jbreak = &breakcell; 73 static CELL contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM, 0 }; 74 CELL *jcont = &contcell; 75 static CELL nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM, 0 }; 76 CELL *jnext = &nextcell; 77 static CELL exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM, 0 }; 78 CELL *jexit = &exitcell; 79 static CELL tempcell ={ OCELL, CTEMP, 0, 0, 0.0, NUM, 0 }; 80 81 run(a) NODE *a; 82 { 83 register int i; 84 85 execute(a); 86 /* Wait for children to complete if output to a pipe. */ 87 for (i=0; i<FILENUM; i++) 88 if (files[i].fp && files[i].type == '|') 89 pclose(files[i].fp); 90 } 91 92 93 CELL *execute(u) NODE *u; 94 { 95 register CELL *(*proc)(); 96 register CELL *x; 97 register NODE *a; 98 99 if (u == NULL) 100 return (true); 101 for (a = u; /* dummy */; a = a->nnext) { 102 if (cantexec(a)) 103 return (nodetoobj(a)); 104 if (notlegal(a->nobj)) 105 error(FATAL, "illegal statement %o", a); 106 proc = proctab[a->nobj-FIRSTTOKEN]; 107 x = (*proc)(a->narg, a->nobj); 108 if (isfld(x)) 109 fldbld(); 110 if (isexpr(a)) 111 return (x); 112 /* a statement, goto next statement */ 113 if (isjump(x)) 114 return (x); 115 if (a->nnext == (NODE *)NULL) 116 return (x); 117 tempfree(x); 118 } 119 } 120 121 122 123 124 CELL *program(a, n) register NODE **a; 125 { 126 register CELL *x; 127 128 if (a[0] != NULL) { 129 x = execute(a[0]); 130 if (isexit(x)) 131 return (true); 132 if (isjump(x)) 133 error(FATAL, "unexpected break, continue or next"); 134 tempfree(x); 135 } 136 while (getrec()) { 137 x = execute(a[1]); 138 if (isexit(x)) { 139 tempfree(x); 140 break; 141 } 142 tempfree(x); 143 } 144 if (a[2] != NULL) { 145 x = execute(a[2]); 146 if (isbreak(x) || isnext(x) || iscont(x)) 147 error(FATAL, "unexpected break, continue or next"); 148 tempfree(x); 149 } 150 return (true); 151 } 152 153 154 155 156 CELL *getline() 157 { 158 register CELL *x; 159 160 x = gettemp(); 161 setfval(x, (awkfloat) getrec()); 162 return (x); 163 } 164 165 166 167 168 CELL *array(a, n) register NODE **a; 169 { 170 register CELL *x, *y; 171 extern CELL *arrayel(); 172 173 x = execute(a[1]); 174 y = arrayel(a[0], x); 175 tempfree(x); 176 return (y); 177 } 178 179 180 181 182 CELL *arrayel(a, b) NODE *a; CELL *b; 183 { 184 register wchar_t *s; 185 register CELL *x; 186 register int i; 187 register CELL *y; 188 189 s = getsval(b); 190 x = (CELL *) a; 191 if (!(x->tval&ARR)) { 192 xfree(x->sval); 193 x->tval &= ~STR; 194 x->tval |= ARR; 195 x->sval = (wchar_t *) makesymtab(); 196 } 197 y = setsymtab(s, tostring(L_NULL), 0.0, STR|NUM, x->sval); 198 y->ctype = OCELL; 199 y->csub = CVAR; 200 return (y); 201 } 202 203 CELL *matchop(a, n) NODE **a; 204 { 205 register CELL *x; 206 register wchar_t *s; 207 register int i; 208 209 x = execute(a[0]); 210 s = getsval(x); 211 tempfree(x); 212 i = match(a[1], s); 213 if (n == MATCH && i == 1 || n == NOTMATCH && i == 0) 214 return (true); 215 else 216 return (false); 217 } 218 219 220 221 222 CELL *boolop(a, n) NODE **a; 223 { 224 register CELL *x, *y; 225 register int i; 226 227 228 229 230 x = execute(a[0]); 231 i = istrue(x); 232 tempfree(x); 233 switch (n) { 234 case BOR: 235 if (i) return (true); 236 y = execute(a[1]); 237 i = istrue(y); 238 tempfree(y); 239 if (i) return (true); 240 else return (false); 241 case AND: 242 if (!i) return (false); 243 y = execute(a[1]); 244 i = istrue(y); 245 tempfree(y); 246 if (i) return (true); 247 else return (false); 248 case NOT: 249 if (i) return (false); 250 else return (true); 251 default: 252 error(FATAL, "unknown boolean operator %d", n); 253 } 254 } 255 256 257 258 259 CELL *relop(a, n) NODE **a; 260 { 261 register int i; 262 register CELL *x, *y; 263 awkfloat j; 264 register wchar_t *xs, *ys; 265 266 267 268 269 x = execute(a[0]); 270 y = execute(a[1]); 271 if (x->tval&NUM && y->tval&NUM) { 272 j = x->fval - y->fval; 273 i = j<0? -1: (j>0? 1: 0); 274 } else { 275 xs = getsval(x); 276 ys = getsval(y); 277 if (xs && ys) 278 i = wscoll(xs, ys); 279 else 280 return (false); 281 } 282 tempfree(x); 283 tempfree(y); 284 switch (n) { 285 case LT: if (i<0) return (true); 286 else return (false); 287 case LE: if (i<=0) return (true); 288 else return (false); 289 case NE: if (i!=0) return (true); 290 else return (false); 291 case EQ: if (i == 0) return (true); 292 else return (false); 293 case GE: if (i>=0) return (true); 294 else return (false); 295 case GT: if (i>0) return (true); 296 else return (false); 297 default: 298 error(FATAL, "unknown relational operator %d", n); 299 } 300 } 301 302 303 304 305 306 307 308 309 CELL *gettemp() 310 { 311 register int i; 312 register CELL *x; 313 314 315 316 317 for (i=0; i<MAXTMP; i++) 318 if (tmps[i].tval == 0) 319 break; 320 if (i == MAXTMP) 321 error(FATAL, "out of temporaries in gettemp"); 322 tmps[i] = tempcell; 323 x = &tmps[i]; 324 return (x); 325 } 326 327 328 329 330 CELL *indirect(a, n) NODE **a; 331 { 332 register CELL *x; 333 register int m; 334 CELL *fieldadr(); 335 336 x = execute(a[0]); 337 m = getfval(x); 338 tempfree(x); 339 x = fieldadr(m); 340 x->ctype = OCELL; 341 x->csub = CFLD; 342 return (x); 343 } 344 345 346 347 348 CELL *substr(a, nnn) NODE **a; 349 { 350 register int k, m, n; 351 register wchar_t *s, temp; 352 register CELL *x, *y; 353 354 y = execute(a[0]); 355 s = getsval(y); 356 k = wslen(s) + 1; 357 if (k <= 1) { 358 x = gettemp(); 359 setsval(x, L_NULL); 360 return (x); 361 } 362 x = execute(a[1]); 363 m = getfval(x); 364 if (m <= 0) 365 m = 1; 366 else if (m > k) 367 m = k; 368 tempfree(x); 369 if (a[2] != 0) { 370 x = execute(a[2]); 371 n = getfval(x); 372 tempfree(x); 373 } 374 else 375 n = k - 1; 376 if (n < 0) 377 n = 0; 378 else if (n > k - m) 379 n = k - m; 380 dprintf("substr: m=%d, n=%d, s=%ws\n", m, n, s); 381 x = gettemp(); 382 temp = s[n+m-1]; 383 s[n+m-1] = (wchar_t)0x0; 384 setsval(x, s + m - 1); 385 s[n+m-1] = temp; 386 tempfree(y); 387 return (x); 388 } 389 390 391 392 393 CELL *sindex(a, nnn) NODE **a; 394 { 395 register CELL *x; 396 register wchar_t *s1, *s2, *p1, *p2, *q; 397 398 x = execute(a[0]); 399 s1 = getsval(x); 400 tempfree(x); 401 x = execute(a[1]); 402 s2 = getsval(x); 403 tempfree(x); 404 405 x = gettemp(); 406 for (p1 = s1; *p1 != (wchar_t)0x0; p1++) { 407 for (q=p1, p2=s2; *p2 != (wchar_t)0x0 && *q == *p2; q++, p2++) 408 ; 409 if (*p2 == (wchar_t)0x0) { 410 setfval(x, (awkfloat) (p1 - s1 + 1)); /* origin 1 */ 411 return (x); 412 } 413 } 414 setfval(x, 0.0); 415 return (x); 416 } 417 418 419 420 421 wchar_t *format(s, a) register wchar_t *s; NODE *a; 422 { 423 register wchar_t *buf, *ep, *str; 424 register wchar_t *p; 425 register char *t; 426 wchar_t *os; 427 wchar_t tbuf[2*RECSIZE]; 428 char fmt[200]; 429 register CELL *x; 430 int flag = 0; 431 awkfloat xf; 432 433 os = s; 434 p = buf= (wchar_t *)malloc(RECSIZE * sizeof (wchar_t)); 435 436 if (p == NULL) 437 error(FATAL, "out of space in format"); 438 ep = p + RECSIZE; 439 while (*s) { 440 if (*s != '%') { 441 *p++ = *s++; 442 continue; 443 } 444 if (*(s+1) == '%') { 445 *p++ = '%'; 446 s += 2; 447 continue; 448 } 449 for (t=fmt; *s != '\0'; s++) 450 { 451 if (*s == 's' || *s == 'c') 452 *t++ = 'w'; 453 *t++ = *s; 454 if (*s >= 'a' && *s <= 'z' && *s != 'l') 455 break; 456 if (*s == '*') { 457 if (a == NULL) { 458 error(FATAL, 459 "not enough arguments in printf(%ws) or sprintf(%ws)", 460 os, os); 461 } 462 x = execute(a); 463 a = a->nnext; 464 sprintf(t-1, "%d", (int) getfval(x)); 465 t = fmt + strlen(fmt); 466 tempfree(x); 467 } 468 469 } 470 *t = '\0'; 471 if (t >= fmt + sizeof (fmt)) 472 error(FATAL, "format item %.20ws... too long", os); 473 switch (*s) { 474 case 'f': case 'e': case 'g': 475 flag = 1; 476 break; 477 case 'd': 478 flag = 2; 479 if (*(s-1) == 'l') break; 480 *(t-1) = 'l'; 481 *t = 'd'; 482 *++t = '\0'; 483 break; 484 case 'o': case 'x': 485 flag = *(s-1) == 'l' ? 2 : 3; 486 break; 487 case 'c': 488 flag = 3; 489 break; 490 case 's': 491 flag = 4; 492 break; 493 default: 494 flag = 0; 495 break; 496 } 497 if (flag == 0) { 498 wsprintf(p, "%s", fmt); 499 p += wslen(p); 500 continue; 501 } 502 if (a == NULL) { 503 error(FATAL, 504 "not enough arguments in printf(%ws) or sprintf(%ws)", os, os); 505 } 506 x = execute(a); 507 a = a->nnext; 508 509 /* 510 * Get the string to check length; %s is the usual problem; 511 * other conversions can cause overrun if they occur when 512 * the buffer is almost filled. 513 */ 514 if (flag == 4) { /* watch out for converting to numbers! */ 515 str = getsval(x); 516 } 517 else { 518 xf = getfval(x); 519 if (flag == 1) wsprintf(tbuf, fmt, xf); 520 else if (flag == 2) wsprintf(tbuf, fmt, (long)xf); 521 else if (flag == 3) wsprintf(tbuf, fmt, (int)xf); 522 if (wslen(tbuf) >= RECSIZE) 523 error(FATAL, "formatted item %s... too long", 524 tbuf); 525 str = tbuf; 526 } 527 /* 528 * If string overruns the buffer, reallocate; 529 * consider length of format string 530 */ 531 if (p + wslen(str) + wslen(s) + 1 >= ep) { 532 int newlen, oldlen; 533 534 oldlen = p - buf; 535 /* Add RECSIZE for additional space */ 536 newlen = oldlen + wslen(str) + RECSIZE; 537 buf = realloc(buf, (unsigned) newlen * sizeof(wchar_t)); 538 if (buf == NULL) 539 error(FATAL, "out of format space"); 540 p = buf + oldlen; 541 ep = buf + newlen; 542 } 543 /* Transfer string to buffer */ 544 if (flag == 4) 545 wsprintf(p, fmt, str); 546 else 547 wscpy(p, str); 548 549 tempfree(x); 550 p += wslen(p); 551 if (p >= ep) 552 error(FATAL, "formatted string too long"); 553 s++; 554 } 555 *p = '\0'; 556 return (buf); 557 } 558 559 560 CELL *asprintf(a, n) NODE **a; 561 { 562 register CELL *x; 563 register NODE *y; 564 register wchar_t *s; 565 566 y = a[0]->nnext; 567 x = execute(a[0]); 568 s = format(getsval(x), y); 569 tempfree(x); 570 x = gettemp(); 571 x->sval = s; 572 x->tval = STR; 573 return (x); 574 } 575 576 577 CELL *arith(a, n) NODE **a; 578 { 579 awkfloat i, j; 580 register CELL *x, *y, *z; 581 582 x = execute(a[0]); 583 i = getfval(x); 584 tempfree(x); 585 if (n != UMINUS) { 586 y = execute(a[1]); 587 j = getfval(y); 588 tempfree(y); 589 } 590 z = gettemp(); 591 switch (n) { 592 case ADD: 593 i += j; 594 break; 595 case MINUS: 596 i -= j; 597 break; 598 case MULT: 599 i *= j; 600 break; 601 case DIVIDE: 602 if (j == 0) 603 error(FATAL, "division by zero"); 604 i /= j; 605 break; 606 case MOD: 607 if (j == 0) 608 error(FATAL, "division by zero"); 609 i = i - j*(long)(i/j); 610 break; 611 case UMINUS: 612 i = -i; 613 break; 614 default: 615 error(FATAL, "illegal arithmetic operator %d", n); 616 } 617 setfval(z, i); 618 return (z); 619 } 620 621 622 623 624 CELL *incrdecr(a, n) NODE **a; 625 { 626 register CELL *x, *z; 627 register int k; 628 awkfloat xf; 629 630 x = execute(a[0]); 631 xf = getfval(x); 632 k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 633 if (n == PREINCR || n == PREDECR) { 634 setfval(x, xf + k); 635 return (x); 636 } 637 z = gettemp(); 638 setfval(z, xf); 639 setfval(x, xf + k); 640 tempfree(x); 641 return (z); 642 } 643 644 645 646 CELL *assign(a, n) NODE **a; 647 { 648 register CELL *x, *y; 649 awkfloat xf, yf; 650 651 652 653 654 x = execute(a[0]); 655 y = execute(a[1]); 656 if (n == ASSIGN) { /* ordinary assignment */ 657 if ((y->tval & (STR|NUM)) == (STR|NUM)) { 658 setsval(x, y->sval); 659 x->fval = y->fval; 660 x->tval |= NUM; 661 662 } else if (y->tval & STR) 663 setsval(x, y->sval); 664 else if (y->tval & NUM) 665 setfval(x, y->fval); 666 tempfree(y); 667 return (x); 668 } 669 xf = getfval(x); 670 yf = getfval(y); 671 switch (n) { 672 case ADDEQ: 673 xf += yf; 674 break; 675 case SUBEQ: 676 xf -= yf; 677 break; 678 case MULTEQ: 679 xf *= yf; 680 break; 681 case DIVEQ: 682 if (yf == 0) 683 error(FATAL, "division by zero"); 684 xf /= yf; 685 break; 686 case MODEQ: 687 if (yf == 0) 688 error(FATAL, "division by zero"); 689 xf = xf - yf*(long)(xf/yf); 690 break; 691 default: 692 error(FATAL, "illegal assignment operator %d", n); 693 break; 694 } 695 tempfree(y); 696 setfval(x, xf); 697 return (x); 698 } 699 700 701 702 703 CELL *cat(a, q) NODE **a; 704 { 705 register CELL *x, *y, *z; 706 register int n1, n2; 707 register wchar_t *s; 708 709 710 711 712 x = execute(a[0]); 713 y = execute(a[1]); 714 getsval(x); 715 getsval(y); 716 n1 = wslen(x->sval); 717 n2 = wslen(y->sval); 718 if ((s = (wchar_t *) malloc((n1 + n2 + 1) * sizeof (wchar_t))) == NULL) 719 error(FATAL, "out of space in cat"); 720 wscpy(s, x->sval); 721 wscpy(s+n1, y->sval); 722 tempfree(y); 723 z = gettemp(); 724 z->sval = s; 725 z->tval = STR; 726 tempfree(x); 727 return (z); 728 } 729 730 731 732 733 CELL *pastat(a, n) NODE **a; 734 { 735 register CELL *x; 736 737 738 739 740 if (a[0] == 0) 741 x = true; 742 else 743 x = execute(a[0]); 744 if (istrue(x)) { 745 tempfree(x); 746 x = execute(a[1]); 747 } 748 return (x); 749 } 750 751 752 753 754 CELL *dopa2(a, n) NODE **a; 755 { 756 register CELL *x; 757 register int pair; 758 759 760 761 762 pair = (int) a[3]; 763 if (pairstack[pair] == 0) { 764 x = execute(a[0]); 765 if (istrue(x)) 766 pairstack[pair] = 1; 767 tempfree(x); 768 } 769 if (pairstack[pair] == 1) { 770 x = execute(a[1]); 771 if (istrue(x)) 772 pairstack[pair] = 0; 773 tempfree(x); 774 x = execute(a[2]); 775 return (x); 776 } 777 return (false); 778 } 779 780 781 782 783 CELL *aprintf(a, n) NODE **a; 784 { 785 register CELL *x; 786 787 788 789 790 x = asprintf(a, n); 791 if (a[1] == NULL) { 792 printf("%ws", x->sval); 793 tempfree(x); 794 return (true); 795 } 796 redirprint(x->sval, (int)a[1], a[2]); 797 return (x); 798 } 799 800 801 802 803 CELL *split(a, nnn) NODE **a; 804 { 805 register CELL *x; 806 register CELL *ap; 807 register wchar_t *s, *p, c; 808 wchar_t *t, temp, num[5]; 809 register wchar_t sep; 810 int n, flag; 811 812 813 814 815 x = execute(a[0]); 816 s = getsval(x); 817 tempfree(x); 818 if (a[2] == 0) 819 sep = **FS; 820 else { 821 x = execute(a[2]); 822 sep = getsval(x)[0]; 823 tempfree(x); 824 } 825 ap = (CELL *) a[1]; 826 freesymtab(ap); 827 dprintf("split: s=|%ws|, a=%ws, sep=|%wc|\n", s, ap->nval, sep); 828 ap->tval &= ~STR; 829 ap->tval |= ARR; 830 ap->sval = (wchar_t *) makesymtab(); 831 832 833 834 835 n = 0; 836 if (sep == ' ') 837 for (n = 0; /* dummy */; /* dummy */) { 838 c = *s; 839 while (iswblank(c) || c == '\t' || c == '\n') 840 c = *(++s); 841 if (*s == 0) 842 break; 843 n++; 844 t = s; 845 do 846 c = *(++s); 847 while (! iswblank(c) && c != '\t' && 848 c != '\n' && c != '\0'); 849 temp = c; 850 *s = (wchar_t)0x0; 851 wsprintf(num, "%d", n); 852 if (isanumber(t)) 853 setsymtab(num, tostring(t), 854 watof(t), STR|NUM, ap->sval); 855 else 856 setsymtab(num, tostring(t), 0.0, STR, ap->sval); 857 *s = temp; 858 if (*s != 0) 859 s++; 860 861 } else if (*s != 0) 862 for (;;) { 863 n++; 864 t = s; 865 while ((c = *s) != sep && c != '\n' && c != '\0') 866 s++; 867 temp = c; 868 *s = (wchar_t)0x0; 869 wsprintf(num, "%d", n); 870 if (isanumber(t)) 871 setsymtab(num, tostring(t), 872 watof(t), STR|NUM, ap->sval); 873 else 874 setsymtab(num, tostring(t), 0.0, STR, ap->sval); 875 *s = temp; 876 if (*s++ == 0) 877 break; 878 } 879 x = gettemp(); 880 x->tval = NUM; 881 x->fval = n; 882 return (x); 883 } 884 885 886 887 888 CELL *ifstat(a, n) NODE **a; 889 { 890 register CELL *x; 891 892 893 894 895 x = execute(a[0]); 896 if (istrue(x)) { 897 tempfree(x); 898 x = execute(a[1]); 899 900 } else if (a[2] != 0) { 901 tempfree(x); 902 x = execute(a[2]); 903 } 904 return (x); 905 } 906 907 908 909 910 CELL *whilestat(a, n) NODE **a; 911 { 912 register CELL *x; 913 914 915 916 917 for (;;) { 918 x = execute(a[0]); 919 if (!istrue(x)) return (x); 920 tempfree(x); 921 x = execute(a[1]); 922 if (isbreak(x)) { 923 x = true; 924 return (x); 925 } 926 if (isnext(x) || isexit(x)) 927 return (x); 928 tempfree(x); 929 } 930 } 931 932 933 934 935 CELL *forstat(a, n) NODE **a; 936 { 937 register CELL *x; 938 register CELL *z; 939 940 941 942 943 z = execute(a[0]); 944 tempfree(z); 945 for (;;) { 946 if (a[1]!=0) { 947 x = execute(a[1]); 948 if (!istrue(x)) return (x); 949 else tempfree(x); 950 } 951 x = execute(a[3]); 952 if (isbreak(x)) { /* turn off break */ 953 x = true; 954 return (x); 955 } 956 if (isnext(x) || isexit(x)) 957 return (x); 958 tempfree(x); 959 z = execute(a[2]); 960 tempfree(z); 961 } 962 } 963 964 965 966 967 CELL *instat(a, n) NODE **a; 968 { 969 register CELL *vp, *arrayp, *cp, **tp; 970 register CELL *x; 971 int i; 972 973 974 975 976 vp = (CELL *) a[0]; 977 arrayp = (CELL *) a[1]; 978 if (!(arrayp->tval & ARR)) 979 error(FATAL, "%ws is not an array", arrayp->nval); 980 tp = (CELL **) arrayp->sval; 981 for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */ 982 for (cp = tp[i]; cp != NULL; cp = cp->nextval) { 983 setsval(vp, cp->nval); 984 x = execute(a[2]); 985 if (isbreak(x)) { 986 x = true; 987 return (x); 988 } 989 if (isnext(x) || isexit(x)) 990 return (x); 991 tempfree(x); 992 } 993 } 994 return (true); 995 } 996 997 998 999 1000 CELL *jump(a, n) NODE **a; 1001 { 1002 register CELL *y; 1003 1004 1005 1006 1007 switch (n) { 1008 case EXIT: 1009 if (a[0] != 0) { 1010 y = execute(a[0]); 1011 errorflag = getfval(y); 1012 } 1013 return (jexit); 1014 case NEXT: 1015 return (jnext); 1016 case BREAK: 1017 return (jbreak); 1018 case CONTINUE: 1019 return (jcont); 1020 default: 1021 error(FATAL, "illegal jump type %d", n); 1022 } 1023 } 1024 1025 1026 1027 1028 CELL *fncn(a, n) NODE **a; 1029 { 1030 register CELL *x; 1031 awkfloat u; 1032 register int t; 1033 register wchar_t *wp; 1034 1035 t = (int) a[0]; 1036 x = execute(a[1]); 1037 if (t == FLENGTH) 1038 u = (awkfloat) wslen(getsval(x)); 1039 else if (t == FLOG) 1040 u = log(getfval(x)); 1041 else if (t == FINT) 1042 u = (awkfloat) (long) getfval(x); 1043 else if (t == FEXP) 1044 u = exp(getfval(x)); 1045 else if (t == FSQRT) 1046 u = sqrt(getfval(x)); 1047 else 1048 error(FATAL, "illegal function type %d", t); 1049 tempfree(x); 1050 x = gettemp(); 1051 setfval(x, u); 1052 return (x); 1053 } 1054 1055 1056 1057 1058 CELL *print(a, n) NODE **a; 1059 { 1060 register NODE *x; 1061 register CELL *y; 1062 wchar_t s[RECSIZE]; 1063 wchar_t *ss, *bp, *ep; 1064 1065 s[0] = '\0'; 1066 bp = s; 1067 ep = s + RECSIZE; 1068 for (x=a[0]; x!=NULL; x=x->nnext) { 1069 y = execute(x); 1070 ss = getsval(y); 1071 /* allocate larger buffer if needed */ 1072 if (ep < bp + wslen(bp) + wslen(ss)) { 1073 int newlen; 1074 wchar_t *oldbp; 1075 1076 newlen = wslen(bp) + wslen(ss) + 1 + 1; 1077 oldbp = bp; 1078 bp = malloc(newlen * sizeof(wchar_t)); 1079 if (bp == NULL) 1080 error(FATAL, "out of space in print"); 1081 ep = bp + newlen; 1082 wscpy(bp, oldbp); 1083 if (oldbp != s) 1084 free(oldbp); 1085 } 1086 if (ss) 1087 wscat(bp, ss); 1088 tempfree(y); 1089 if (x->nnext == NULL) 1090 wscat(bp, *ORS); 1091 else 1092 wscat(bp, *OFS); 1093 } 1094 if (a[1] == 0) { 1095 printf("%ws", bp); 1096 if (bp != s) 1097 free(bp); 1098 return (true); 1099 } 1100 1101 redirprint(bp, (int)a[1], a[2]); 1102 if (bp != s) 1103 free(bp); 1104 return (false); 1105 } 1106 1107 1108 1109 1110 CELL *nullproc() {} 1111 1112 1113 1114 1115 CELL *nodetoobj(a) NODE *a; 1116 { 1117 register CELL *x; 1118 1119 x= (CELL *) a->nobj; 1120 x->ctype = OCELL; 1121 x->csub = a->subtype; 1122 if (isfld(x)) 1123 fldbld(); 1124 return (x); 1125 } 1126 1127 redirprint(s, a, b) wchar_t *s; NODE *b; 1128 { 1129 register int i; 1130 register CELL *x; 1131 1132 x = execute(b); 1133 getsval(x); 1134 for (i=0; i<FILENUM; i++) 1135 if (files[i].fname && wscmp(x->sval, files[i].fname) == 0) 1136 goto doit; 1137 for (i=0; i<FILENUM; i++) 1138 if (files[i].fp == 0) 1139 break; 1140 if (i >= FILENUM) 1141 error(FATAL, "too many output files %d", i); 1142 if (a == '|') /* a pipe! */ 1143 files[i].fp = popen(toeuccode(x->sval), "w"); 1144 else if (a == APPEND) 1145 files[i].fp = fopen(toeuccode(x->sval), "a"); 1146 else if (a == GT) 1147 files[i].fp = fopen(toeuccode(x->sval), "w"); 1148 else 1149 error(FATAL, "illegal redirection near line %lld", lineno); 1150 if (files[i].fp == NULL) 1151 error(FATAL, "can't open file %ws", x->sval); 1152 files[i].fname = tostring(x->sval); 1153 files[i].type = a; 1154 doit: 1155 fprintf(files[i].fp, "%ws", s); 1156 #ifndef gcos 1157 fflush(files[i].fp); /* in case someone is waiting for the output */ 1158 #endif 1159 tempfree(x); 1160 } 1161