1 /**************************************************************** 2 Copyright (C) Lucent Technologies 1997 3 All Rights Reserved 4 5 Permission to use, copy, modify, and distribute this software and 6 its documentation for any purpose and without fee is hereby 7 granted, provided that the above copyright notice appear in all 8 copies and that both that the copyright notice and this 9 permission notice and warranty disclaimer appear in supporting 10 documentation, and that the name Lucent Technologies or any of 11 its entities not be used in advertising or publicity pertaining 12 to distribution of the software without specific, written prior 13 permission. 14 15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22 THIS SOFTWARE. 23 ****************************************************************/ 24 25 #include <sys/cdefs.h> 26 __FBSDID("$FreeBSD$"); 27 28 #define DEBUG 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <setjmp.h> 32 #include <limits.h> 33 #include <math.h> 34 #include <string.h> 35 #include <stdlib.h> 36 #include <time.h> 37 #include "awk.h" 38 #include "ytab.h" 39 40 #define tempfree(x) if (istemp(x)) tfree(x); else 41 42 /* 43 #undef tempfree 44 45 void tempfree(Cell *p) { 46 if (p->ctype == OCELL && (p->csub < CUNK || p->csub > CFREE)) { 47 WARNING("bad csub %d in Cell %d %s", 48 p->csub, p->ctype, p->sval); 49 } 50 if (istemp(p)) 51 tfree(p); 52 } 53 */ 54 55 /* do we really need these? */ 56 /* #ifdef _NFILE */ 57 /* #ifndef FOPEN_MAX */ 58 /* #define FOPEN_MAX _NFILE */ 59 /* #endif */ 60 /* #endif */ 61 /* */ 62 /* #ifndef FOPEN_MAX */ 63 /* #define FOPEN_MAX 40 */ /* max number of open files */ 64 /* #endif */ 65 /* */ 66 /* #ifndef RAND_MAX */ 67 /* #define RAND_MAX 32767 */ /* all that ansi guarantees */ 68 /* #endif */ 69 70 jmp_buf env; 71 extern int pairstack[]; 72 extern Awkfloat srand_seed; 73 74 Node *winner = NULL; /* root of parse tree */ 75 Cell *tmps; /* free temporary cells for execution */ 76 77 static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; 78 Cell *True = &truecell; 79 static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; 80 Cell *False = &falsecell; 81 static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; 82 Cell *jbreak = &breakcell; 83 static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; 84 Cell *jcont = &contcell; 85 static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM }; 86 Cell *jnext = &nextcell; 87 static Cell nextfilecell ={ OJUMP, JNEXTFILE, 0, 0, 0.0, NUM }; 88 Cell *jnextfile = &nextfilecell; 89 static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM }; 90 Cell *jexit = &exitcell; 91 static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM }; 92 Cell *jret = &retcell; 93 static Cell tempcell ={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE }; 94 95 Node *curnode = NULL; /* the node being executed, for debugging */ 96 97 /* buffer memory management */ 98 int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, 99 const char *whatrtn) 100 /* pbuf: address of pointer to buffer being managed 101 * psiz: address of buffer size variable 102 * minlen: minimum length of buffer needed 103 * quantum: buffer size quantum 104 * pbptr: address of movable pointer into buffer, or 0 if none 105 * whatrtn: name of the calling routine if failure should cause fatal error 106 * 107 * return 0 for realloc failure, !=0 for success 108 */ 109 { 110 if (minlen > *psiz) { 111 char *tbuf; 112 int rminlen = quantum ? minlen % quantum : 0; 113 int boff = pbptr ? *pbptr - *pbuf : 0; 114 /* round up to next multiple of quantum */ 115 if (rminlen) 116 minlen += quantum - rminlen; 117 tbuf = (char *) realloc(*pbuf, minlen); 118 dprintf( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) ); 119 if (tbuf == NULL) { 120 if (whatrtn) 121 FATAL("out of memory in %s", whatrtn); 122 return 0; 123 } 124 *pbuf = tbuf; 125 *psiz = minlen; 126 if (pbptr) 127 *pbptr = tbuf + boff; 128 } 129 return 1; 130 } 131 132 void run(Node *a) /* execution of parse tree starts here */ 133 { 134 extern void stdinit(void); 135 136 stdinit(); 137 execute(a); 138 closeall(); 139 } 140 141 Cell *execute(Node *u) /* execute a node of the parse tree */ 142 { 143 Cell *(*proc)(Node **, int); 144 Cell *x; 145 Node *a; 146 147 if (u == NULL) 148 return(True); 149 for (a = u; ; a = a->nnext) { 150 curnode = a; 151 if (isvalue(a)) { 152 x = (Cell *) (a->narg[0]); 153 if (isfld(x) && !donefld) 154 fldbld(); 155 else if (isrec(x) && !donerec) 156 recbld(); 157 return(x); 158 } 159 if (notlegal(a->nobj)) /* probably a Cell* but too risky to print */ 160 FATAL("illegal statement"); 161 proc = proctab[a->nobj-FIRSTTOKEN]; 162 x = (*proc)(a->narg, a->nobj); 163 if (isfld(x) && !donefld) 164 fldbld(); 165 else if (isrec(x) && !donerec) 166 recbld(); 167 if (isexpr(a)) 168 return(x); 169 if (isjump(x)) 170 return(x); 171 if (a->nnext == NULL) 172 return(x); 173 tempfree(x); 174 } 175 } 176 177 178 Cell *program(Node **a, int n) /* execute an awk program */ 179 { /* a[0] = BEGIN, a[1] = body, a[2] = END */ 180 Cell *x; 181 182 if (setjmp(env) != 0) 183 goto ex; 184 if (a[0]) { /* BEGIN */ 185 x = execute(a[0]); 186 if (isexit(x)) 187 return(True); 188 if (isjump(x)) 189 FATAL("illegal break, continue, next or nextfile from BEGIN"); 190 tempfree(x); 191 } 192 if (a[1] || a[2]) 193 while (getrec(&record, &recsize, 1) > 0) { 194 x = execute(a[1]); 195 if (isexit(x)) 196 break; 197 tempfree(x); 198 } 199 ex: 200 if (setjmp(env) != 0) /* handles exit within END */ 201 goto ex1; 202 if (a[2]) { /* END */ 203 x = execute(a[2]); 204 if (isbreak(x) || isnext(x) || iscont(x)) 205 FATAL("illegal break, continue, next or nextfile from END"); 206 tempfree(x); 207 } 208 ex1: 209 return(True); 210 } 211 212 struct Frame { /* stack frame for awk function calls */ 213 int nargs; /* number of arguments in this call */ 214 Cell *fcncell; /* pointer to Cell for function */ 215 Cell **args; /* pointer to array of arguments after execute */ 216 Cell *retval; /* return value */ 217 }; 218 219 #define NARGS 50 /* max args in a call */ 220 221 struct Frame *frame = NULL; /* base of stack frames; dynamically allocated */ 222 int nframe = 0; /* number of frames allocated */ 223 struct Frame *fp = NULL; /* frame pointer. bottom level unused */ 224 225 Cell *call(Node **a, int n) /* function call. very kludgy and fragile */ 226 { 227 static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE }; 228 int i, ncall, ndef; 229 int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */ 230 Node *x; 231 Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */ 232 Cell *y, *z, *fcn; 233 char *s; 234 235 fcn = execute(a[0]); /* the function itself */ 236 s = fcn->nval; 237 if (!isfcn(fcn)) 238 FATAL("calling undefined function %s", s); 239 if (frame == NULL) { 240 fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame)); 241 if (frame == NULL) 242 FATAL("out of space for stack frames calling %s", s); 243 } 244 for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ 245 ncall++; 246 ndef = (int) fcn->fval; /* args in defn */ 247 dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) ); 248 if (ncall > ndef) 249 WARNING("function %s called with %d args, uses only %d", 250 s, ncall, ndef); 251 if (ncall + ndef > NARGS) 252 FATAL("function %s has %d arguments, limit %d", s, ncall+ndef, NARGS); 253 for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ 254 dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) ); 255 y = execute(x); 256 oargs[i] = y; 257 dprintf( ("args[%d]: %s %f <%s>, t=%o\n", 258 i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) ); 259 if (isfcn(y)) 260 FATAL("can't use function %s as argument in %s", y->nval, s); 261 if (isarr(y)) 262 args[i] = y; /* arrays by ref */ 263 else 264 args[i] = copycell(y); 265 tempfree(y); 266 } 267 for ( ; i < ndef; i++) { /* add null args for ones not provided */ 268 args[i] = gettemp(); 269 *args[i] = newcopycell; 270 } 271 fp++; /* now ok to up frame */ 272 if (fp >= frame + nframe) { 273 int dfp = fp - frame; /* old index */ 274 frame = (struct Frame *) 275 realloc((char *) frame, (nframe += 100) * sizeof(struct Frame)); 276 if (frame == NULL) 277 FATAL("out of space for stack frames in %s", s); 278 fp = frame + dfp; 279 } 280 fp->fcncell = fcn; 281 fp->args = args; 282 fp->nargs = ndef; /* number defined with (excess are locals) */ 283 fp->retval = gettemp(); 284 285 dprintf( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) ); 286 y = execute((Node *)(fcn->sval)); /* execute body */ 287 dprintf( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) ); 288 289 for (i = 0; i < ndef; i++) { 290 Cell *t = fp->args[i]; 291 if (isarr(t)) { 292 if (t->csub == CCOPY) { 293 if (i >= ncall) { 294 freesymtab(t); 295 t->csub = CTEMP; 296 tempfree(t); 297 } else { 298 oargs[i]->tval = t->tval; 299 oargs[i]->tval &= ~(STR|NUM|DONTFREE); 300 oargs[i]->sval = t->sval; 301 tempfree(t); 302 } 303 } 304 } else if (t != y) { /* kludge to prevent freeing twice */ 305 t->csub = CTEMP; 306 tempfree(t); 307 } else if (t == y && t->csub == CCOPY) { 308 t->csub = CTEMP; 309 tempfree(t); 310 freed = 1; 311 } 312 } 313 tempfree(fcn); 314 if (isexit(y) || isnext(y)) 315 return y; 316 if (freed == 0) { 317 tempfree(y); /* don't free twice! */ 318 } 319 z = fp->retval; /* return value */ 320 dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) ); 321 fp--; 322 return(z); 323 } 324 325 Cell *copycell(Cell *x) /* make a copy of a cell in a temp */ 326 { 327 Cell *y; 328 329 y = gettemp(); 330 y->csub = CCOPY; /* prevents freeing until call is over */ 331 y->nval = x->nval; /* BUG? */ 332 if (isstr(x)) 333 y->sval = tostring(x->sval); 334 y->fval = x->fval; 335 y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); /* copy is not constant or field */ 336 /* is DONTFREE right? */ 337 return y; 338 } 339 340 Cell *arg(Node **a, int n) /* nth argument of a function */ 341 { 342 343 n = ptoi(a[0]); /* argument number, counting from 0 */ 344 dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) ); 345 if (n+1 > fp->nargs) 346 FATAL("argument #%d of function %s was not supplied", 347 n+1, fp->fcncell->nval); 348 return fp->args[n]; 349 } 350 351 Cell *jump(Node **a, int n) /* break, continue, next, nextfile, return */ 352 { 353 Cell *y; 354 355 switch (n) { 356 case EXIT: 357 if (a[0] != NULL) { 358 y = execute(a[0]); 359 errorflag = (int) getfval(y); 360 tempfree(y); 361 } 362 longjmp(env, 1); 363 case RETURN: 364 if (a[0] != NULL) { 365 y = execute(a[0]); 366 if ((y->tval & (STR|NUM)) == (STR|NUM)) { 367 setsval(fp->retval, getsval(y)); 368 fp->retval->fval = getfval(y); 369 fp->retval->tval |= NUM; 370 } 371 else if (y->tval & STR) 372 setsval(fp->retval, getsval(y)); 373 else if (y->tval & NUM) 374 setfval(fp->retval, getfval(y)); 375 else /* can't happen */ 376 FATAL("bad type variable %d", y->tval); 377 tempfree(y); 378 } 379 return(jret); 380 case NEXT: 381 return(jnext); 382 case NEXTFILE: 383 nextfile(); 384 return(jnextfile); 385 case BREAK: 386 return(jbreak); 387 case CONTINUE: 388 return(jcont); 389 default: /* can't happen */ 390 FATAL("illegal jump type %d", n); 391 } 392 return 0; /* not reached */ 393 } 394 395 Cell *awkgetline(Node **a, int n) /* get next line from specific input */ 396 { /* a[0] is variable, a[1] is operator, a[2] is filename */ 397 Cell *r, *x; 398 extern Cell **fldtab; 399 FILE *fp; 400 char *buf; 401 int bufsize = recsize; 402 int mode; 403 404 if ((buf = (char *) malloc(bufsize)) == NULL) 405 FATAL("out of memory in getline"); 406 407 fflush(stdout); /* in case someone is waiting for a prompt */ 408 r = gettemp(); 409 if (a[1] != NULL) { /* getline < file */ 410 x = execute(a[2]); /* filename */ 411 mode = ptoi(a[1]); 412 if (mode == '|') /* input pipe */ 413 mode = LE; /* arbitrary flag */ 414 fp = openfile(mode, getsval(x)); 415 tempfree(x); 416 if (fp == NULL) 417 n = -1; 418 else 419 n = readrec(&buf, &bufsize, fp); 420 if (n <= 0) { 421 ; 422 } else if (a[0] != NULL) { /* getline var <file */ 423 x = execute(a[0]); 424 setsval(x, buf); 425 tempfree(x); 426 } else { /* getline <file */ 427 setsval(fldtab[0], buf); 428 if (is_number(fldtab[0]->sval)) { 429 fldtab[0]->fval = atof(fldtab[0]->sval); 430 fldtab[0]->tval |= NUM; 431 } 432 } 433 } else { /* bare getline; use current input */ 434 if (a[0] == NULL) /* getline */ 435 n = getrec(&record, &recsize, 1); 436 else { /* getline var */ 437 n = getrec(&buf, &bufsize, 0); 438 x = execute(a[0]); 439 setsval(x, buf); 440 tempfree(x); 441 } 442 } 443 setfval(r, (Awkfloat) n); 444 free(buf); 445 return r; 446 } 447 448 Cell *getnf(Node **a, int n) /* get NF */ 449 { 450 if (donefld == 0) 451 fldbld(); 452 return (Cell *) a[0]; 453 } 454 455 Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ 456 { 457 Cell *x, *y, *z; 458 char *s; 459 Node *np; 460 char *buf; 461 int bufsz = recsize; 462 int nsub = strlen(*SUBSEP); 463 464 if ((buf = (char *) malloc(bufsz)) == NULL) 465 FATAL("out of memory in array"); 466 467 x = execute(a[0]); /* Cell* for symbol table */ 468 buf[0] = 0; 469 for (np = a[1]; np; np = np->nnext) { 470 y = execute(np); /* subscript */ 471 s = getsval(y); 472 if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array")) 473 FATAL("out of memory for %s[%s...]", x->nval, buf); 474 strcat(buf, s); 475 if (np->nnext) 476 strcat(buf, *SUBSEP); 477 tempfree(y); 478 } 479 if (!isarr(x)) { 480 dprintf( ("making %s into an array\n", NN(x->nval)) ); 481 if (freeable(x)) 482 xfree(x->sval); 483 x->tval &= ~(STR|NUM|DONTFREE); 484 x->tval |= ARR; 485 x->sval = (char *) makesymtab(NSYMTAB); 486 } 487 z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval); 488 z->ctype = OCELL; 489 z->csub = CVAR; 490 tempfree(x); 491 free(buf); 492 return(z); 493 } 494 495 Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ 496 { 497 Cell *x, *y; 498 Node *np; 499 char *s; 500 int nsub = strlen(*SUBSEP); 501 502 x = execute(a[0]); /* Cell* for symbol table */ 503 if (!isarr(x)) 504 return True; 505 if (a[1] == NULL) { /* delete the elements, not the table */ 506 freesymtab(x); 507 x->tval &= ~STR; 508 x->tval |= ARR; 509 x->sval = (char *) makesymtab(NSYMTAB); 510 } else { 511 int bufsz = recsize; 512 char *buf; 513 if ((buf = (char *) malloc(bufsz)) == NULL) 514 FATAL("out of memory in adelete"); 515 buf[0] = 0; 516 for (np = a[1]; np; np = np->nnext) { 517 y = execute(np); /* subscript */ 518 s = getsval(y); 519 if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete")) 520 FATAL("out of memory deleting %s[%s...]", x->nval, buf); 521 strcat(buf, s); 522 if (np->nnext) 523 strcat(buf, *SUBSEP); 524 tempfree(y); 525 } 526 freeelem(x, buf); 527 free(buf); 528 } 529 tempfree(x); 530 return True; 531 } 532 533 Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ 534 { 535 Cell *x, *ap, *k; 536 Node *p; 537 char *buf; 538 char *s; 539 int bufsz = recsize; 540 int nsub = strlen(*SUBSEP); 541 542 ap = execute(a[1]); /* array name */ 543 if (!isarr(ap)) { 544 dprintf( ("making %s into an array\n", ap->nval) ); 545 if (freeable(ap)) 546 xfree(ap->sval); 547 ap->tval &= ~(STR|NUM|DONTFREE); 548 ap->tval |= ARR; 549 ap->sval = (char *) makesymtab(NSYMTAB); 550 } 551 if ((buf = (char *) malloc(bufsz)) == NULL) { 552 FATAL("out of memory in intest"); 553 } 554 buf[0] = 0; 555 for (p = a[0]; p; p = p->nnext) { 556 x = execute(p); /* expr */ 557 s = getsval(x); 558 if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest")) 559 FATAL("out of memory deleting %s[%s...]", x->nval, buf); 560 strcat(buf, s); 561 tempfree(x); 562 if (p->nnext) 563 strcat(buf, *SUBSEP); 564 } 565 k = lookup(buf, (Array *) ap->sval); 566 tempfree(ap); 567 free(buf); 568 if (k == NULL) 569 return(False); 570 else 571 return(True); 572 } 573 574 575 Cell *matchop(Node **a, int n) /* ~ and match() */ 576 { 577 Cell *x, *y; 578 char *s, *t; 579 int i; 580 fa *pfa; 581 int (*mf)(fa *, const char *) = match, mode = 0; 582 583 if (n == MATCHFCN) { 584 mf = pmatch; 585 mode = 1; 586 } 587 x = execute(a[1]); /* a[1] = target text */ 588 s = getsval(x); 589 if (a[0] == NULL) /* a[1] == 0: already-compiled reg expr */ 590 i = (*mf)((fa *) a[2], s); 591 else { 592 y = execute(a[2]); /* a[2] = regular expr */ 593 t = getsval(y); 594 pfa = makedfa(t, mode); 595 i = (*mf)(pfa, s); 596 tempfree(y); 597 } 598 tempfree(x); 599 if (n == MATCHFCN) { 600 int start = patbeg - s + 1; 601 if (patlen < 0) 602 start = 0; 603 setfval(rstartloc, (Awkfloat) start); 604 setfval(rlengthloc, (Awkfloat) patlen); 605 x = gettemp(); 606 x->tval = NUM; 607 x->fval = start; 608 return x; 609 } else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0)) 610 return(True); 611 else 612 return(False); 613 } 614 615 616 Cell *boolop(Node **a, int n) /* a[0] || a[1], a[0] && a[1], !a[0] */ 617 { 618 Cell *x, *y; 619 int i; 620 621 x = execute(a[0]); 622 i = istrue(x); 623 tempfree(x); 624 switch (n) { 625 case BOR: 626 if (i) return(True); 627 y = execute(a[1]); 628 i = istrue(y); 629 tempfree(y); 630 if (i) return(True); 631 else return(False); 632 case AND: 633 if ( !i ) return(False); 634 y = execute(a[1]); 635 i = istrue(y); 636 tempfree(y); 637 if (i) return(True); 638 else return(False); 639 case NOT: 640 if (i) return(False); 641 else return(True); 642 default: /* can't happen */ 643 FATAL("unknown boolean operator %d", n); 644 } 645 return 0; /*NOTREACHED*/ 646 } 647 648 Cell *relop(Node **a, int n) /* a[0 < a[1], etc. */ 649 { 650 int i; 651 Cell *x, *y; 652 Awkfloat j; 653 654 x = execute(a[0]); 655 y = execute(a[1]); 656 if (x->tval&NUM && y->tval&NUM) { 657 j = x->fval - y->fval; 658 i = j<0? -1: (j>0? 1: 0); 659 } else { 660 i = strcoll(getsval(x), getsval(y)); 661 } 662 tempfree(x); 663 tempfree(y); 664 switch (n) { 665 case LT: if (i<0) return(True); 666 else return(False); 667 case LE: if (i<=0) return(True); 668 else return(False); 669 case NE: if (i!=0) return(True); 670 else return(False); 671 case EQ: if (i == 0) return(True); 672 else return(False); 673 case GE: if (i>=0) return(True); 674 else return(False); 675 case GT: if (i>0) return(True); 676 else return(False); 677 default: /* can't happen */ 678 FATAL("unknown relational operator %d", n); 679 } 680 return 0; /*NOTREACHED*/ 681 } 682 683 void tfree(Cell *a) /* free a tempcell */ 684 { 685 if (freeable(a)) { 686 dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) ); 687 xfree(a->sval); 688 } 689 if (a == tmps) 690 FATAL("tempcell list is curdled"); 691 a->cnext = tmps; 692 tmps = a; 693 } 694 695 Cell *gettemp(void) /* get a tempcell */ 696 { int i; 697 Cell *x; 698 699 if (!tmps) { 700 tmps = (Cell *) calloc(100, sizeof(Cell)); 701 if (!tmps) 702 FATAL("out of space for temporaries"); 703 for(i = 1; i < 100; i++) 704 tmps[i-1].cnext = &tmps[i]; 705 tmps[i-1].cnext = NULL; 706 } 707 x = tmps; 708 tmps = x->cnext; 709 *x = tempcell; 710 return(x); 711 } 712 713 Cell *indirect(Node **a, int n) /* $( a[0] ) */ 714 { 715 Awkfloat val; 716 Cell *x; 717 int m; 718 char *s; 719 720 x = execute(a[0]); 721 val = getfval(x); /* freebsd: defend against super large field numbers */ 722 if ((Awkfloat)INT_MAX < val) 723 FATAL("trying to access out of range field %s", x->nval); 724 m = (int) val; 725 if (m == 0 && !is_number(s = getsval(x))) /* suspicion! */ 726 FATAL("illegal field $(%s), name \"%s\"", s, x->nval); 727 /* BUG: can x->nval ever be null??? */ 728 tempfree(x); 729 x = fieldadr(m); 730 x->ctype = OCELL; /* BUG? why are these needed? */ 731 x->csub = CFLD; 732 return(x); 733 } 734 735 Cell *substr(Node **a, int nnn) /* substr(a[0], a[1], a[2]) */ 736 { 737 int k, m, n; 738 char *s; 739 int temp; 740 Cell *x, *y, *z = NULL; 741 742 x = execute(a[0]); 743 y = execute(a[1]); 744 if (a[2] != NULL) 745 z = execute(a[2]); 746 s = getsval(x); 747 k = strlen(s) + 1; 748 if (k <= 1) { 749 tempfree(x); 750 tempfree(y); 751 if (a[2] != NULL) { 752 tempfree(z); 753 } 754 x = gettemp(); 755 setsval(x, ""); 756 return(x); 757 } 758 m = (int) getfval(y); 759 if (m <= 0) 760 m = 1; 761 else if (m > k) 762 m = k; 763 tempfree(y); 764 if (a[2] != NULL) { 765 n = (int) getfval(z); 766 tempfree(z); 767 } else 768 n = k - 1; 769 if (n < 0) 770 n = 0; 771 else if (n > k - m) 772 n = k - m; 773 dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) ); 774 y = gettemp(); 775 temp = s[n+m-1]; /* with thanks to John Linderman */ 776 s[n+m-1] = '\0'; 777 setsval(y, s + m - 1); 778 s[n+m-1] = temp; 779 tempfree(x); 780 return(y); 781 } 782 783 Cell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */ 784 { 785 Cell *x, *y, *z; 786 char *s1, *s2, *p1, *p2, *q; 787 Awkfloat v = 0.0; 788 789 x = execute(a[0]); 790 s1 = getsval(x); 791 y = execute(a[1]); 792 s2 = getsval(y); 793 794 z = gettemp(); 795 for (p1 = s1; *p1 != '\0'; p1++) { 796 for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) 797 ; 798 if (*p2 == '\0') { 799 v = (Awkfloat) (p1 - s1 + 1); /* origin 1 */ 800 break; 801 } 802 } 803 tempfree(x); 804 tempfree(y); 805 setfval(z, v); 806 return(z); 807 } 808 809 #define MAXNUMSIZE 50 810 811 int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */ 812 { 813 char *fmt; 814 char *p, *t; 815 const char *os; 816 Cell *x; 817 int flag = 0, n; 818 int fmtwd; /* format width */ 819 int fmtsz = recsize; 820 char *buf = *pbuf; 821 int bufsize = *pbufsize; 822 823 os = s; 824 p = buf; 825 if ((fmt = (char *) malloc(fmtsz)) == NULL) 826 FATAL("out of memory in format()"); 827 while (*s) { 828 adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1"); 829 if (*s != '%') { 830 *p++ = *s++; 831 continue; 832 } 833 if (*(s+1) == '%') { 834 *p++ = '%'; 835 s += 2; 836 continue; 837 } 838 /* have to be real careful in case this is a huge number, eg, %100000d */ 839 fmtwd = atoi(s+1); 840 if (fmtwd < 0) 841 fmtwd = -fmtwd; 842 adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format2"); 843 for (t = fmt; (*t++ = *s) != '\0'; s++) { 844 if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, "format3")) 845 FATAL("format item %.30s... ran format() out of memory", os); 846 if (isalpha((uschar)*s) && *s != 'l' && *s != 'h' && *s != 'L') 847 break; /* the ansi panoply */ 848 if (*s == '*') { 849 x = execute(a); 850 a = a->nnext; 851 sprintf(t-1, "%d", fmtwd=(int) getfval(x)); 852 if (fmtwd < 0) 853 fmtwd = -fmtwd; 854 adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format"); 855 t = fmt + strlen(fmt); 856 tempfree(x); 857 } 858 } 859 *t = '\0'; 860 if (fmtwd < 0) 861 fmtwd = -fmtwd; 862 adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format4"); 863 864 switch (*s) { 865 case 'f': case 'e': case 'g': case 'E': case 'G': 866 flag = 'f'; 867 break; 868 case 'd': case 'i': 869 flag = 'd'; 870 if(*(s-1) == 'l') break; 871 *(t-1) = 'l'; 872 *t = 'd'; 873 *++t = '\0'; 874 break; 875 case 'o': case 'x': case 'X': case 'u': 876 flag = *(s-1) == 'l' ? 'd' : 'u'; 877 break; 878 case 's': 879 flag = 's'; 880 break; 881 case 'c': 882 flag = 'c'; 883 break; 884 default: 885 WARNING("weird printf conversion %s", fmt); 886 flag = '?'; 887 break; 888 } 889 if (a == NULL) 890 FATAL("not enough args in printf(%s)", os); 891 x = execute(a); 892 a = a->nnext; 893 n = MAXNUMSIZE; 894 if (fmtwd > n) 895 n = fmtwd; 896 adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5"); 897 switch (flag) { 898 case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */ 899 t = getsval(x); 900 n = strlen(t); 901 if (fmtwd > n) 902 n = fmtwd; 903 adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6"); 904 p += strlen(p); 905 sprintf(p, "%s", t); 906 break; 907 case 'f': sprintf(p, fmt, getfval(x)); break; 908 case 'd': sprintf(p, fmt, (long) getfval(x)); break; 909 case 'u': sprintf(p, fmt, (int) getfval(x)); break; 910 case 's': 911 t = getsval(x); 912 n = strlen(t); 913 if (fmtwd > n) 914 n = fmtwd; 915 if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7")) 916 FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); 917 sprintf(p, fmt, t); 918 break; 919 case 'c': 920 if (isnum(x)) { 921 if ((int)getfval(x)) 922 sprintf(p, fmt, (int) getfval(x)); 923 else { 924 *p++ = '\0'; /* explicit null byte */ 925 *p = '\0'; /* next output will start here */ 926 } 927 } else 928 sprintf(p, fmt, getsval(x)[0]); 929 break; 930 default: 931 FATAL("can't happen: bad conversion %c in format()", flag); 932 } 933 tempfree(x); 934 p += strlen(p); 935 s++; 936 } 937 *p = '\0'; 938 free(fmt); 939 for ( ; a; a = a->nnext) /* evaluate any remaining args */ 940 execute(a); 941 *pbuf = buf; 942 *pbufsize = bufsize; 943 return p - buf; 944 } 945 946 Cell *awksprintf(Node **a, int n) /* sprintf(a[0]) */ 947 { 948 Cell *x; 949 Node *y; 950 char *buf; 951 int bufsz=3*recsize; 952 953 if ((buf = (char *) malloc(bufsz)) == NULL) 954 FATAL("out of memory in awksprintf"); 955 y = a[0]->nnext; 956 x = execute(a[0]); 957 if (format(&buf, &bufsz, getsval(x), y) == -1) 958 FATAL("sprintf string %.30s... too long. can't happen.", buf); 959 tempfree(x); 960 x = gettemp(); 961 x->sval = buf; 962 x->tval = STR; 963 return(x); 964 } 965 966 Cell *awkprintf(Node **a, int n) /* printf */ 967 { /* a[0] is list of args, starting with format string */ 968 /* a[1] is redirection operator, a[2] is redirection file */ 969 FILE *fp; 970 Cell *x; 971 Node *y; 972 char *buf; 973 int len; 974 int bufsz=3*recsize; 975 976 if ((buf = (char *) malloc(bufsz)) == NULL) 977 FATAL("out of memory in awkprintf"); 978 y = a[0]->nnext; 979 x = execute(a[0]); 980 if ((len = format(&buf, &bufsz, getsval(x), y)) == -1) 981 FATAL("printf string %.30s... too long. can't happen.", buf); 982 tempfree(x); 983 if (a[1] == NULL) { 984 /* fputs(buf, stdout); */ 985 fwrite(buf, len, 1, stdout); 986 if (ferror(stdout)) 987 FATAL("write error on stdout"); 988 } else { 989 fp = redirect(ptoi(a[1]), a[2]); 990 /* fputs(buf, fp); */ 991 fwrite(buf, len, 1, fp); 992 fflush(fp); 993 if (ferror(fp)) 994 FATAL("write error on %s", filename(fp)); 995 } 996 free(buf); 997 return(True); 998 } 999 1000 Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */ 1001 { 1002 Awkfloat i, j = 0; 1003 double v; 1004 Cell *x, *y, *z; 1005 1006 x = execute(a[0]); 1007 i = getfval(x); 1008 tempfree(x); 1009 if (n != UMINUS) { 1010 y = execute(a[1]); 1011 j = getfval(y); 1012 tempfree(y); 1013 } 1014 z = gettemp(); 1015 switch (n) { 1016 case ADD: 1017 i += j; 1018 break; 1019 case MINUS: 1020 i -= j; 1021 break; 1022 case MULT: 1023 i *= j; 1024 break; 1025 case DIVIDE: 1026 if (j == 0) 1027 FATAL("division by zero"); 1028 i /= j; 1029 break; 1030 case MOD: 1031 if (j == 0) 1032 FATAL("division by zero in mod"); 1033 modf(i/j, &v); 1034 i = i - j * v; 1035 break; 1036 case UMINUS: 1037 i = -i; 1038 break; 1039 case POWER: 1040 if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */ 1041 i = ipow(i, (int) j); 1042 else 1043 i = errcheck(pow(i, j), "pow"); 1044 break; 1045 default: /* can't happen */ 1046 FATAL("illegal arithmetic operator %d", n); 1047 } 1048 setfval(z, i); 1049 return(z); 1050 } 1051 1052 double ipow(double x, int n) /* x**n. ought to be done by pow, but isn't always */ 1053 { 1054 double v; 1055 1056 if (n <= 0) 1057 return 1; 1058 v = ipow(x, n/2); 1059 if (n % 2 == 0) 1060 return v * v; 1061 else 1062 return x * v * v; 1063 } 1064 1065 Cell *incrdecr(Node **a, int n) /* a[0]++, etc. */ 1066 { 1067 Cell *x, *z; 1068 int k; 1069 Awkfloat xf; 1070 1071 x = execute(a[0]); 1072 xf = getfval(x); 1073 k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 1074 if (n == PREINCR || n == PREDECR) { 1075 setfval(x, xf + k); 1076 return(x); 1077 } 1078 z = gettemp(); 1079 setfval(z, xf); 1080 setfval(x, xf + k); 1081 tempfree(x); 1082 return(z); 1083 } 1084 1085 Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ 1086 { /* this is subtle; don't muck with it. */ 1087 Cell *x, *y; 1088 Awkfloat xf, yf; 1089 double v; 1090 1091 y = execute(a[1]); 1092 x = execute(a[0]); 1093 if (n == ASSIGN) { /* ordinary assignment */ 1094 if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */ 1095 ; /* leave alone unless it's a field */ 1096 else if ((y->tval & (STR|NUM)) == (STR|NUM)) { 1097 setsval(x, getsval(y)); 1098 x->fval = getfval(y); 1099 x->tval |= NUM; 1100 } 1101 else if (isstr(y)) 1102 setsval(x, getsval(y)); 1103 else if (isnum(y)) 1104 setfval(x, getfval(y)); 1105 else 1106 funnyvar(y, "read value of"); 1107 tempfree(y); 1108 return(x); 1109 } 1110 xf = getfval(x); 1111 yf = getfval(y); 1112 switch (n) { 1113 case ADDEQ: 1114 xf += yf; 1115 break; 1116 case SUBEQ: 1117 xf -= yf; 1118 break; 1119 case MULTEQ: 1120 xf *= yf; 1121 break; 1122 case DIVEQ: 1123 if (yf == 0) 1124 FATAL("division by zero in /="); 1125 xf /= yf; 1126 break; 1127 case MODEQ: 1128 if (yf == 0) 1129 FATAL("division by zero in %%="); 1130 modf(xf/yf, &v); 1131 xf = xf - yf * v; 1132 break; 1133 case POWEQ: 1134 if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ 1135 xf = ipow(xf, (int) yf); 1136 else 1137 xf = errcheck(pow(xf, yf), "pow"); 1138 break; 1139 default: 1140 FATAL("illegal assignment operator %d", n); 1141 break; 1142 } 1143 tempfree(y); 1144 setfval(x, xf); 1145 return(x); 1146 } 1147 1148 Cell *cat(Node **a, int q) /* a[0] cat a[1] */ 1149 { 1150 Cell *x, *y, *z; 1151 int n1, n2; 1152 char *s; 1153 1154 x = execute(a[0]); 1155 y = execute(a[1]); 1156 getsval(x); 1157 getsval(y); 1158 n1 = strlen(x->sval); 1159 n2 = strlen(y->sval); 1160 s = (char *) malloc(n1 + n2 + 1); 1161 if (s == NULL) 1162 FATAL("out of space concatenating %.15s... and %.15s...", 1163 x->sval, y->sval); 1164 strcpy(s, x->sval); 1165 strcpy(s+n1, y->sval); 1166 tempfree(x); 1167 tempfree(y); 1168 z = gettemp(); 1169 z->sval = s; 1170 z->tval = STR; 1171 return(z); 1172 } 1173 1174 Cell *pastat(Node **a, int n) /* a[0] { a[1] } */ 1175 { 1176 Cell *x; 1177 1178 if (a[0] == NULL) 1179 x = execute(a[1]); 1180 else { 1181 x = execute(a[0]); 1182 if (istrue(x)) { 1183 tempfree(x); 1184 x = execute(a[1]); 1185 } 1186 } 1187 return x; 1188 } 1189 1190 Cell *dopa2(Node **a, int n) /* a[0], a[1] { a[2] } */ 1191 { 1192 Cell *x; 1193 int pair; 1194 1195 pair = ptoi(a[3]); 1196 if (pairstack[pair] == 0) { 1197 x = execute(a[0]); 1198 if (istrue(x)) 1199 pairstack[pair] = 1; 1200 tempfree(x); 1201 } 1202 if (pairstack[pair] == 1) { 1203 x = execute(a[1]); 1204 if (istrue(x)) 1205 pairstack[pair] = 0; 1206 tempfree(x); 1207 x = execute(a[2]); 1208 return(x); 1209 } 1210 return(False); 1211 } 1212 1213 Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ 1214 { 1215 Cell *x = NULL, *y, *ap; 1216 char *s, *origs; 1217 int sep; 1218 char *t, temp, num[50], *fs = NULL; 1219 int n, tempstat, arg3type; 1220 1221 y = execute(a[0]); /* source string */ 1222 origs = s = strdup(getsval(y)); 1223 arg3type = ptoi(a[3]); 1224 if (a[2] == NULL) /* fs string */ 1225 fs = *FS; 1226 else if (arg3type == STRING) { /* split(str,arr,"string") */ 1227 x = execute(a[2]); 1228 fs = getsval(x); 1229 } else if (arg3type == REGEXPR) 1230 fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ 1231 else 1232 FATAL("illegal type of split"); 1233 sep = *fs; 1234 ap = execute(a[1]); /* array name */ 1235 freesymtab(ap); 1236 dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); 1237 ap->tval &= ~STR; 1238 ap->tval |= ARR; 1239 ap->sval = (char *) makesymtab(NSYMTAB); 1240 1241 n = 0; 1242 if (arg3type == REGEXPR && strlen((char*)((fa*)a[2])->restr) == 0) { 1243 /* split(s, a, //); have to arrange that it looks like empty sep */ 1244 arg3type = 0; 1245 fs = ""; 1246 sep = 0; 1247 } 1248 if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */ 1249 fa *pfa; 1250 if (arg3type == REGEXPR) { /* it's ready already */ 1251 pfa = (fa *) a[2]; 1252 } else { 1253 pfa = makedfa(fs, 1); 1254 } 1255 if (nematch(pfa,s)) { 1256 tempstat = pfa->initstat; 1257 pfa->initstat = 2; 1258 do { 1259 n++; 1260 sprintf(num, "%d", n); 1261 temp = *patbeg; 1262 *patbeg = '\0'; 1263 if (is_number(s)) 1264 setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); 1265 else 1266 setsymtab(num, s, 0.0, STR, (Array *) ap->sval); 1267 *patbeg = temp; 1268 s = patbeg + patlen; 1269 if (*(patbeg+patlen-1) == 0 || *s == 0) { 1270 n++; 1271 sprintf(num, "%d", n); 1272 setsymtab(num, "", 0.0, STR, (Array *) ap->sval); 1273 pfa->initstat = tempstat; 1274 goto spdone; 1275 } 1276 } while (nematch(pfa,s)); 1277 pfa->initstat = tempstat; /* bwk: has to be here to reset */ 1278 /* cf gsub and refldbld */ 1279 } 1280 n++; 1281 sprintf(num, "%d", n); 1282 if (is_number(s)) 1283 setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); 1284 else 1285 setsymtab(num, s, 0.0, STR, (Array *) ap->sval); 1286 spdone: 1287 pfa = NULL; 1288 } else if (sep == ' ') { 1289 for (n = 0; ; ) { 1290 while (*s == ' ' || *s == '\t' || *s == '\n') 1291 s++; 1292 if (*s == 0) 1293 break; 1294 n++; 1295 t = s; 1296 do 1297 s++; 1298 while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); 1299 temp = *s; 1300 *s = '\0'; 1301 sprintf(num, "%d", n); 1302 if (is_number(t)) 1303 setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); 1304 else 1305 setsymtab(num, t, 0.0, STR, (Array *) ap->sval); 1306 *s = temp; 1307 if (*s != 0) 1308 s++; 1309 } 1310 } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ 1311 for (n = 0; *s != 0; s++) { 1312 char buf[2]; 1313 n++; 1314 sprintf(num, "%d", n); 1315 buf[0] = *s; 1316 buf[1] = 0; 1317 if (isdigit((uschar)buf[0])) 1318 setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); 1319 else 1320 setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); 1321 } 1322 } else if (*s != 0) { 1323 for (;;) { 1324 n++; 1325 t = s; 1326 while (*s != sep && *s != '\n' && *s != '\0') 1327 s++; 1328 temp = *s; 1329 *s = '\0'; 1330 sprintf(num, "%d", n); 1331 if (is_number(t)) 1332 setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); 1333 else 1334 setsymtab(num, t, 0.0, STR, (Array *) ap->sval); 1335 *s = temp; 1336 if (*s++ == 0) 1337 break; 1338 } 1339 } 1340 tempfree(ap); 1341 tempfree(y); 1342 free(origs); 1343 if (a[2] != NULL && arg3type == STRING) { 1344 tempfree(x); 1345 } 1346 x = gettemp(); 1347 x->tval = NUM; 1348 x->fval = n; 1349 return(x); 1350 } 1351 1352 Cell *condexpr(Node **a, int n) /* a[0] ? a[1] : a[2] */ 1353 { 1354 Cell *x; 1355 1356 x = execute(a[0]); 1357 if (istrue(x)) { 1358 tempfree(x); 1359 x = execute(a[1]); 1360 } else { 1361 tempfree(x); 1362 x = execute(a[2]); 1363 } 1364 return(x); 1365 } 1366 1367 Cell *ifstat(Node **a, int n) /* if (a[0]) a[1]; else a[2] */ 1368 { 1369 Cell *x; 1370 1371 x = execute(a[0]); 1372 if (istrue(x)) { 1373 tempfree(x); 1374 x = execute(a[1]); 1375 } else if (a[2] != NULL) { 1376 tempfree(x); 1377 x = execute(a[2]); 1378 } 1379 return(x); 1380 } 1381 1382 Cell *whilestat(Node **a, int n) /* while (a[0]) a[1] */ 1383 { 1384 Cell *x; 1385 1386 for (;;) { 1387 x = execute(a[0]); 1388 if (!istrue(x)) 1389 return(x); 1390 tempfree(x); 1391 x = execute(a[1]); 1392 if (isbreak(x)) { 1393 x = True; 1394 return(x); 1395 } 1396 if (isnext(x) || isexit(x) || isret(x)) 1397 return(x); 1398 tempfree(x); 1399 } 1400 } 1401 1402 Cell *dostat(Node **a, int n) /* do a[0]; while(a[1]) */ 1403 { 1404 Cell *x; 1405 1406 for (;;) { 1407 x = execute(a[0]); 1408 if (isbreak(x)) 1409 return True; 1410 if (isnext(x) || isexit(x) || isret(x)) 1411 return(x); 1412 tempfree(x); 1413 x = execute(a[1]); 1414 if (!istrue(x)) 1415 return(x); 1416 tempfree(x); 1417 } 1418 } 1419 1420 Cell *forstat(Node **a, int n) /* for (a[0]; a[1]; a[2]) a[3] */ 1421 { 1422 Cell *x; 1423 1424 x = execute(a[0]); 1425 tempfree(x); 1426 for (;;) { 1427 if (a[1]!=NULL) { 1428 x = execute(a[1]); 1429 if (!istrue(x)) return(x); 1430 else tempfree(x); 1431 } 1432 x = execute(a[3]); 1433 if (isbreak(x)) /* turn off break */ 1434 return True; 1435 if (isnext(x) || isexit(x) || isret(x)) 1436 return(x); 1437 tempfree(x); 1438 x = execute(a[2]); 1439 tempfree(x); 1440 } 1441 } 1442 1443 Cell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */ 1444 { 1445 Cell *x, *vp, *arrayp, *cp, *ncp; 1446 Array *tp; 1447 int i; 1448 1449 vp = execute(a[0]); 1450 arrayp = execute(a[1]); 1451 if (!isarr(arrayp)) { 1452 return True; 1453 } 1454 tp = (Array *) arrayp->sval; 1455 tempfree(arrayp); 1456 for (i = 0; i < tp->size; i++) { /* this routine knows too much */ 1457 for (cp = tp->tab[i]; cp != NULL; cp = ncp) { 1458 setsval(vp, cp->nval); 1459 ncp = cp->cnext; 1460 x = execute(a[2]); 1461 if (isbreak(x)) { 1462 tempfree(vp); 1463 return True; 1464 } 1465 if (isnext(x) || isexit(x) || isret(x)) { 1466 tempfree(vp); 1467 return(x); 1468 } 1469 tempfree(x); 1470 } 1471 } 1472 return True; 1473 } 1474 1475 Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ 1476 { 1477 Cell *x, *y; 1478 Awkfloat u; 1479 int t, i; 1480 Awkfloat tmp; 1481 char *p, *buf; 1482 Node *nextarg; 1483 FILE *fp; 1484 void flush_all(void); 1485 1486 t = ptoi(a[0]); 1487 x = execute(a[1]); 1488 nextarg = a[1]->nnext; 1489 switch (t) { 1490 case FLENGTH: 1491 if (isarr(x)) 1492 u = ((Array *) x->sval)->nelem; /* GROT. should be function*/ 1493 else 1494 u = strlen(getsval(x)); 1495 break; 1496 case FLOG: 1497 u = errcheck(log(getfval(x)), "log"); break; 1498 case FINT: 1499 modf(getfval(x), &u); break; 1500 case FEXP: 1501 u = errcheck(exp(getfval(x)), "exp"); break; 1502 case FSQRT: 1503 u = errcheck(sqrt(getfval(x)), "sqrt"); break; 1504 case FSIN: 1505 u = sin(getfval(x)); break; 1506 case FCOS: 1507 u = cos(getfval(x)); break; 1508 case FATAN: 1509 if (nextarg == NULL) { 1510 WARNING("atan2 requires two arguments; returning 1.0"); 1511 u = 1.0; 1512 } else { 1513 y = execute(a[1]->nnext); 1514 u = atan2(getfval(x), getfval(y)); 1515 tempfree(y); 1516 nextarg = nextarg->nnext; 1517 } 1518 break; 1519 case FCOMPL: 1520 u = ~((int)getfval(x)); 1521 break; 1522 case FAND: 1523 if (nextarg == NULL) { 1524 WARNING("and requires two arguments; returning 0"); 1525 u = 0; 1526 break; 1527 } 1528 i = ((int)getfval(x)); 1529 while (nextarg != NULL) { 1530 y = execute(nextarg); 1531 i &= (int)getfval(y); 1532 tempfree(y); 1533 nextarg = nextarg->nnext; 1534 } 1535 u = i; 1536 break; 1537 case FFOR: 1538 if (nextarg == NULL) { 1539 WARNING("or requires two arguments; returning 0"); 1540 u = 0; 1541 break; 1542 } 1543 i = ((int)getfval(x)); 1544 while (nextarg != NULL) { 1545 y = execute(nextarg); 1546 i |= (int)getfval(y); 1547 tempfree(y); 1548 nextarg = nextarg->nnext; 1549 } 1550 u = i; 1551 break; 1552 case FXOR: 1553 if (nextarg == NULL) { 1554 WARNING("xor requires two arguments; returning 0"); 1555 u = 0; 1556 break; 1557 } 1558 i = ((int)getfval(x)); 1559 while (nextarg != NULL) { 1560 y = execute(nextarg); 1561 i ^= (int)getfval(y); 1562 tempfree(y); 1563 nextarg = nextarg->nnext; 1564 } 1565 u = i; 1566 break; 1567 case FLSHIFT: 1568 if (nextarg == NULL) { 1569 WARNING("lshift requires two arguments; returning 0"); 1570 u = 0; 1571 break; 1572 } 1573 y = execute(a[1]->nnext); 1574 u = ((int)getfval(x)) << ((int)getfval(y)); 1575 tempfree(y); 1576 nextarg = nextarg->nnext; 1577 break; 1578 case FRSHIFT: 1579 if (nextarg == NULL) { 1580 WARNING("rshift requires two arguments; returning 0"); 1581 u = 0; 1582 break; 1583 } 1584 y = execute(a[1]->nnext); 1585 u = ((int)getfval(x)) >> ((int)getfval(y)); 1586 tempfree(y); 1587 nextarg = nextarg->nnext; 1588 break; 1589 case FSYSTEM: 1590 fflush(stdout); /* in case something is buffered already */ 1591 u = (Awkfloat) system(getsval(x)) / 256; /* 256 is unix-dep */ 1592 break; 1593 case FRAND: 1594 /* random() returns numbers in [0..2^31-1] 1595 * in order to get a number in [0, 1), divide it by 2^31 1596 */ 1597 u = (Awkfloat) random() / (0x7fffffffL + 0x1UL); 1598 break; 1599 case FSRAND: 1600 if (isrec(x)) /* no argument provided */ 1601 u = time((time_t *)0); 1602 else 1603 u = getfval(x); 1604 tmp = u; 1605 srandom((unsigned long) u); 1606 u = srand_seed; 1607 srand_seed = tmp; 1608 break; 1609 case FTOUPPER: 1610 case FTOLOWER: 1611 buf = tostring(getsval(x)); 1612 if (t == FTOUPPER) { 1613 for (p = buf; *p; p++) 1614 if (islower((uschar) *p)) 1615 *p = toupper((uschar)*p); 1616 } else { 1617 for (p = buf; *p; p++) 1618 if (isupper((uschar) *p)) 1619 *p = tolower((uschar)*p); 1620 } 1621 tempfree(x); 1622 x = gettemp(); 1623 setsval(x, buf); 1624 free(buf); 1625 return x; 1626 case FFLUSH: 1627 if (isrec(x) || strlen(getsval(x)) == 0) { 1628 flush_all(); /* fflush() or fflush("") -> all */ 1629 u = 0; 1630 } else if ((fp = openfile(FFLUSH, getsval(x))) == NULL) 1631 u = EOF; 1632 else 1633 u = fflush(fp); 1634 break; 1635 default: /* can't happen */ 1636 FATAL("illegal function type %d", t); 1637 break; 1638 } 1639 tempfree(x); 1640 x = gettemp(); 1641 setfval(x, u); 1642 if (nextarg != NULL) { 1643 WARNING("warning: function has too many arguments"); 1644 for ( ; nextarg; nextarg = nextarg->nnext) 1645 execute(nextarg); 1646 } 1647 return(x); 1648 } 1649 1650 Cell *printstat(Node **a, int n) /* print a[0] */ 1651 { 1652 Node *x; 1653 Cell *y; 1654 FILE *fp; 1655 1656 if (a[1] == NULL) /* a[1] is redirection operator, a[2] is file */ 1657 fp = stdout; 1658 else 1659 fp = redirect(ptoi(a[1]), a[2]); 1660 for (x = a[0]; x != NULL; x = x->nnext) { 1661 y = execute(x); 1662 fputs(getpssval(y), fp); 1663 tempfree(y); 1664 if (x->nnext == NULL) 1665 fputs(*ORS, fp); 1666 else 1667 fputs(*OFS, fp); 1668 } 1669 if (a[1] != NULL) 1670 fflush(fp); 1671 if (ferror(fp)) 1672 FATAL("write error on %s", filename(fp)); 1673 return(True); 1674 } 1675 1676 Cell *nullproc(Node **a, int n) 1677 { 1678 n = n; 1679 a = a; 1680 return 0; 1681 } 1682 1683 1684 FILE *redirect(int a, Node *b) /* set up all i/o redirections */ 1685 { 1686 FILE *fp; 1687 Cell *x; 1688 char *fname; 1689 1690 x = execute(b); 1691 fname = getsval(x); 1692 fp = openfile(a, fname); 1693 if (fp == NULL) 1694 FATAL("can't open file %s", fname); 1695 tempfree(x); 1696 return fp; 1697 } 1698 1699 struct files { 1700 FILE *fp; 1701 const char *fname; 1702 int mode; /* '|', 'a', 'w' => LE/LT, GT */ 1703 } *files; 1704 1705 int nfiles; 1706 1707 void stdinit(void) /* in case stdin, etc., are not constants */ 1708 { 1709 nfiles = FOPEN_MAX; 1710 files = calloc(nfiles, sizeof(*files)); 1711 if (files == NULL) 1712 FATAL("can't allocate file memory for %u files", nfiles); 1713 files[0].fp = stdin; 1714 files[0].fname = "/dev/stdin"; 1715 files[0].mode = LT; 1716 files[1].fp = stdout; 1717 files[1].fname = "/dev/stdout"; 1718 files[1].mode = GT; 1719 files[2].fp = stderr; 1720 files[2].fname = "/dev/stderr"; 1721 files[2].mode = GT; 1722 } 1723 1724 FILE *openfile(int a, const char *us) 1725 { 1726 const char *s = us; 1727 int i, m; 1728 FILE *fp = NULL; 1729 1730 if (*s == '\0') 1731 FATAL("null file name in print or getline"); 1732 for (i=0; i < nfiles; i++) 1733 if (files[i].fname && strcmp(s, files[i].fname) == 0) { 1734 if (a == files[i].mode || (a==APPEND && files[i].mode==GT)) 1735 return files[i].fp; 1736 if (a == FFLUSH) 1737 return files[i].fp; 1738 } 1739 if (a == FFLUSH) /* didn't find it, so don't create it! */ 1740 return NULL; 1741 1742 for (i=0; i < nfiles; i++) 1743 if (files[i].fp == NULL) 1744 break; 1745 if (i >= nfiles) { 1746 struct files *nf; 1747 int nnf = nfiles + FOPEN_MAX; 1748 nf = realloc(files, nnf * sizeof(*nf)); 1749 if (nf == NULL) 1750 FATAL("cannot grow files for %s and %d files", s, nnf); 1751 memset(&nf[nfiles], 0, FOPEN_MAX * sizeof(*nf)); 1752 nfiles = nnf; 1753 files = nf; 1754 } 1755 fflush(stdout); /* force a semblance of order */ 1756 m = a; 1757 if (a == GT) { 1758 fp = fopen(s, "w"); 1759 } else if (a == APPEND) { 1760 fp = fopen(s, "a"); 1761 m = GT; /* so can mix > and >> */ 1762 } else if (a == '|') { /* output pipe */ 1763 fp = popen(s, "w"); 1764 } else if (a == LE) { /* input pipe */ 1765 fp = popen(s, "r"); 1766 } else if (a == LT) { /* getline <file */ 1767 fp = strcmp(s, "-") == 0 ? stdin : fopen(s, "r"); /* "-" is stdin */ 1768 } else /* can't happen */ 1769 FATAL("illegal redirection %d", a); 1770 if (fp != NULL) { 1771 files[i].fname = tostring(s); 1772 files[i].fp = fp; 1773 files[i].mode = m; 1774 } 1775 return fp; 1776 } 1777 1778 const char *filename(FILE *fp) 1779 { 1780 int i; 1781 1782 for (i = 0; i < nfiles; i++) 1783 if (fp == files[i].fp) 1784 return files[i].fname; 1785 return "???"; 1786 } 1787 1788 Cell *closefile(Node **a, int n) 1789 { 1790 Cell *x; 1791 int i, stat; 1792 1793 n = n; 1794 x = execute(a[0]); 1795 getsval(x); 1796 stat = -1; 1797 for (i = 0; i < nfiles; i++) { 1798 if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) { 1799 if (ferror(files[i].fp)) 1800 WARNING( "i/o error occurred on %s", files[i].fname ); 1801 if (files[i].mode == '|' || files[i].mode == LE) 1802 stat = pclose(files[i].fp); 1803 else 1804 stat = fclose(files[i].fp); 1805 if (stat == EOF) 1806 WARNING( "i/o error occurred closing %s", files[i].fname ); 1807 if (i > 2) /* don't do /dev/std... */ 1808 xfree(files[i].fname); 1809 files[i].fname = NULL; /* watch out for ref thru this */ 1810 files[i].fp = NULL; 1811 } 1812 } 1813 tempfree(x); 1814 x = gettemp(); 1815 setfval(x, (Awkfloat) stat); 1816 return(x); 1817 } 1818 1819 void closeall(void) 1820 { 1821 int i, stat; 1822 1823 for (i = 0; i < FOPEN_MAX; i++) { 1824 if (files[i].fp) { 1825 if (ferror(files[i].fp)) 1826 WARNING( "i/o error occurred on %s", files[i].fname ); 1827 if (files[i].mode == '|' || files[i].mode == LE) 1828 stat = pclose(files[i].fp); 1829 else 1830 stat = fclose(files[i].fp); 1831 if (stat == EOF) 1832 WARNING( "i/o error occurred while closing %s", files[i].fname ); 1833 } 1834 } 1835 } 1836 1837 void flush_all(void) 1838 { 1839 int i; 1840 1841 for (i = 0; i < nfiles; i++) 1842 if (files[i].fp) 1843 fflush(files[i].fp); 1844 } 1845 1846 void backsub(char **pb_ptr, char **sptr_ptr); 1847 1848 Cell *sub(Node **a, int nnn) /* substitute command */ 1849 { 1850 char *sptr, *pb, *q; 1851 Cell *x, *y, *result; 1852 char *t, *buf; 1853 fa *pfa; 1854 int bufsz = recsize; 1855 1856 if ((buf = (char *) malloc(bufsz)) == NULL) 1857 FATAL("out of memory in sub"); 1858 x = execute(a[3]); /* target string */ 1859 t = getsval(x); 1860 if (a[0] == NULL) /* 0 => a[1] is already-compiled regexpr */ 1861 pfa = (fa *) a[1]; /* regular expression */ 1862 else { 1863 y = execute(a[1]); 1864 pfa = makedfa(getsval(y), 1); 1865 tempfree(y); 1866 } 1867 y = execute(a[2]); /* replacement string */ 1868 result = False; 1869 if (pmatch(pfa, t)) { 1870 sptr = t; 1871 adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); 1872 pb = buf; 1873 while (sptr < patbeg) 1874 *pb++ = *sptr++; 1875 sptr = getsval(y); 1876 while (*sptr != 0) { 1877 adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub"); 1878 if (*sptr == '\\') { 1879 backsub(&pb, &sptr); 1880 } else if (*sptr == '&') { 1881 sptr++; 1882 adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub"); 1883 for (q = patbeg; q < patbeg+patlen; ) 1884 *pb++ = *q++; 1885 } else 1886 *pb++ = *sptr++; 1887 } 1888 *pb = '\0'; 1889 if (pb > buf + bufsz) 1890 FATAL("sub result1 %.30s too big; can't happen", buf); 1891 sptr = patbeg + patlen; 1892 if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { 1893 adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub"); 1894 while ((*pb++ = *sptr++) != 0) 1895 ; 1896 } 1897 if (pb > buf + bufsz) 1898 FATAL("sub result2 %.30s too big; can't happen", buf); 1899 setsval(x, buf); /* BUG: should be able to avoid copy */ 1900 result = True; 1901 } 1902 tempfree(x); 1903 tempfree(y); 1904 free(buf); 1905 return result; 1906 } 1907 1908 Cell *gsub(Node **a, int nnn) /* global substitute */ 1909 { 1910 Cell *x, *y; 1911 char *rptr, *sptr, *t, *pb, *q; 1912 char *buf; 1913 fa *pfa; 1914 int mflag, tempstat, num; 1915 int bufsz = recsize; 1916 1917 if ((buf = (char *) malloc(bufsz)) == NULL) 1918 FATAL("out of memory in gsub"); 1919 mflag = 0; /* if mflag == 0, can replace empty string */ 1920 num = 0; 1921 x = execute(a[3]); /* target string */ 1922 t = getsval(x); 1923 if (a[0] == NULL) /* 0 => a[1] is already-compiled regexpr */ 1924 pfa = (fa *) a[1]; /* regular expression */ 1925 else { 1926 y = execute(a[1]); 1927 pfa = makedfa(getsval(y), 1); 1928 tempfree(y); 1929 } 1930 y = execute(a[2]); /* replacement string */ 1931 if (pmatch(pfa, t)) { 1932 tempstat = pfa->initstat; 1933 pfa->initstat = 2; 1934 pb = buf; 1935 rptr = getsval(y); 1936 do { 1937 if (patlen == 0 && *patbeg != 0) { /* matched empty string */ 1938 if (mflag == 0) { /* can replace empty */ 1939 num++; 1940 sptr = rptr; 1941 while (*sptr != 0) { 1942 adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); 1943 if (*sptr == '\\') { 1944 backsub(&pb, &sptr); 1945 } else if (*sptr == '&') { 1946 sptr++; 1947 adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); 1948 for (q = patbeg; q < patbeg+patlen; ) 1949 *pb++ = *q++; 1950 } else 1951 *pb++ = *sptr++; 1952 } 1953 } 1954 if (*t == 0) /* at end */ 1955 goto done; 1956 adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub"); 1957 *pb++ = *t++; 1958 if (pb > buf + bufsz) /* BUG: not sure of this test */ 1959 FATAL("gsub result0 %.30s too big; can't happen", buf); 1960 mflag = 0; 1961 } 1962 else { /* matched nonempty string */ 1963 num++; 1964 sptr = t; 1965 adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub"); 1966 while (sptr < patbeg) 1967 *pb++ = *sptr++; 1968 sptr = rptr; 1969 while (*sptr != 0) { 1970 adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); 1971 if (*sptr == '\\') { 1972 backsub(&pb, &sptr); 1973 } else if (*sptr == '&') { 1974 sptr++; 1975 adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); 1976 for (q = patbeg; q < patbeg+patlen; ) 1977 *pb++ = *q++; 1978 } else 1979 *pb++ = *sptr++; 1980 } 1981 t = patbeg + patlen; 1982 if (patlen == 0 || *t == 0 || *(t-1) == 0) 1983 goto done; 1984 if (pb > buf + bufsz) 1985 FATAL("gsub result1 %.30s too big; can't happen", buf); 1986 mflag = 1; 1987 } 1988 } while (pmatch(pfa,t)); 1989 sptr = t; 1990 adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); 1991 while ((*pb++ = *sptr++) != 0) 1992 ; 1993 done: if (pb < buf + bufsz) 1994 *pb = '\0'; 1995 else if (*(pb-1) != '\0') 1996 FATAL("gsub result2 %.30s truncated; can't happen", buf); 1997 setsval(x, buf); /* BUG: should be able to avoid copy + free */ 1998 pfa->initstat = tempstat; 1999 } 2000 tempfree(x); 2001 tempfree(y); 2002 x = gettemp(); 2003 x->tval = NUM; 2004 x->fval = num; 2005 free(buf); 2006 return(x); 2007 } 2008 2009 void backsub(char **pb_ptr, char **sptr_ptr) /* handle \\& variations */ 2010 { /* sptr[0] == '\\' */ 2011 char *pb = *pb_ptr, *sptr = *sptr_ptr; 2012 2013 if (sptr[1] == '\\') { 2014 if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ 2015 *pb++ = '\\'; 2016 *pb++ = '&'; 2017 sptr += 4; 2018 } else if (sptr[2] == '&') { /* \\& -> \ + matched */ 2019 *pb++ = '\\'; 2020 sptr += 2; 2021 } else { /* \\x -> \\x */ 2022 *pb++ = *sptr++; 2023 *pb++ = *sptr++; 2024 } 2025 } else if (sptr[1] == '&') { /* literal & */ 2026 sptr++; 2027 *pb++ = *sptr++; 2028 } else /* literal \ */ 2029 *pb++ = *sptr++; 2030 2031 *pb_ptr = pb; 2032 *sptr_ptr = sptr; 2033 } 2034