1 /* $OpenBSD: run.c,v 1.34 2013/09/29 15:42:25 deraadt Exp $ */ 2 /**************************************************************** 3 Copyright (C) Lucent Technologies 1997 4 All Rights Reserved 5 6 Permission to use, copy, modify, and distribute this software and 7 its documentation for any purpose and without fee is hereby 8 granted, provided that the above copyright notice appear in all 9 copies and that both that the copyright notice and this 10 permission notice and warranty disclaimer appear in supporting 11 documentation, and that the name Lucent Technologies or any of 12 its entities not be used in advertising or publicity pertaining 13 to distribution of the software without specific, written prior 14 permission. 15 16 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 18 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 19 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 21 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 23 THIS SOFTWARE. 24 ****************************************************************/ 25 26 #define DEBUG 27 #include <stdio.h> 28 #include <ctype.h> 29 #include <setjmp.h> 30 #include <limits.h> 31 #include <math.h> 32 #include <string.h> 33 #include <stdlib.h> 34 #include <time.h> 35 #include "awk.h" 36 #include "ytab.h" 37 38 #define tempfree(x) if (istemp(x)) tfree(x); else 39 40 /* 41 #undef tempfree 42 43 void tempfree(Cell *p) { 44 if (p->ctype == OCELL && (p->csub < CUNK || p->csub > CFREE)) { 45 WARNING("bad csub %d in Cell %d %s", 46 p->csub, p->ctype, p->sval); 47 } 48 if (istemp(p)) 49 tfree(p); 50 } 51 */ 52 53 /* do we really need these? */ 54 /* #ifdef _NFILE */ 55 /* #ifndef FOPEN_MAX */ 56 /* #define FOPEN_MAX _NFILE */ 57 /* #endif */ 58 /* #endif */ 59 /* */ 60 /* #ifndef FOPEN_MAX */ 61 /* #define FOPEN_MAX 40 */ /* max number of open files */ 62 /* #endif */ 63 /* */ 64 /* #ifndef RAND_MAX */ 65 /* #define RAND_MAX 32767 */ /* all that ansi guarantees */ 66 /* #endif */ 67 68 jmp_buf env; 69 int use_srandom; 70 extern int pairstack[]; 71 extern Awkfloat srand_seed; 72 73 Node *winner = NULL; /* root of parse tree */ 74 Cell *tmps; /* free temporary cells for execution */ 75 76 static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; 77 Cell *True = &truecell; 78 static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; 79 Cell *False = &falsecell; 80 static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; 81 Cell *jbreak = &breakcell; 82 static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; 83 Cell *jcont = &contcell; 84 static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM }; 85 Cell *jnext = &nextcell; 86 static Cell nextfilecell ={ OJUMP, JNEXTFILE, 0, 0, 0.0, NUM }; 87 Cell *jnextfile = &nextfilecell; 88 static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM }; 89 Cell *jexit = &exitcell; 90 static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM }; 91 Cell *jret = &retcell; 92 static Cell tempcell ={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE }; 93 94 Node *curnode = NULL; /* the node being executed, for debugging */ 95 96 void stdinit(void); 97 void flush_all(void); 98 99 /* buffer memory management */ 100 int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, 101 const char *whatrtn) 102 /* pbuf: address of pointer to buffer being managed 103 * psiz: address of buffer size variable 104 * minlen: minimum length of buffer needed 105 * quantum: buffer size quantum 106 * pbptr: address of movable pointer into buffer, or 0 if none 107 * whatrtn: name of the calling routine if failure should cause fatal error 108 * 109 * return 0 for realloc failure, !=0 for success 110 */ 111 { 112 if (minlen > *psiz) { 113 char *tbuf; 114 int rminlen = quantum ? minlen % quantum : 0; 115 int boff = pbptr ? *pbptr - *pbuf : 0; 116 /* round up to next multiple of quantum */ 117 if (rminlen) 118 minlen += quantum - rminlen; 119 tbuf = (char *) realloc(*pbuf, minlen); 120 dprintf( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) ); 121 if (tbuf == NULL) { 122 if (whatrtn) 123 FATAL("out of memory in %s", whatrtn); 124 return 0; 125 } 126 *pbuf = tbuf; 127 *psiz = minlen; 128 if (pbptr) 129 *pbptr = tbuf + boff; 130 } 131 return 1; 132 } 133 134 void run(Node *a) /* execution of parse tree starts here */ 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 strlcat(buf, s, bufsz); 475 if (np->nnext) 476 strlcat(buf, *SUBSEP, bufsz); 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] == 0) { /* 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 strlcat(buf, s, bufsz); 522 if (np->nnext) 523 strlcat(buf, *SUBSEP, bufsz); 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 strlcat(buf, s, bufsz); 561 tempfree(x); 562 if (p->nnext) 563 strlcat(buf, *SUBSEP, bufsz); 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] == 0) /* 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 = strcmp(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 = 0; 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 = 0; 741 742 x = execute(a[0]); 743 y = execute(a[1]); 744 if (a[2] != 0) 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] != 0) { 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] != 0) { 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 if (a == NULL) 850 FATAL("not enough args in printf(%s)", os); 851 x = execute(a); 852 a = a->nnext; 853 snprintf(t-1, fmt + fmtsz - (t-1), "%d", fmtwd=(int) getfval(x)); 854 if (fmtwd < 0) 855 fmtwd = -fmtwd; 856 adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format"); 857 t = fmt + strlen(fmt); 858 tempfree(x); 859 } 860 } 861 *t = '\0'; 862 if (fmtwd < 0) 863 fmtwd = -fmtwd; 864 adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format4"); 865 866 switch (*s) { 867 case 'f': case 'e': case 'g': case 'E': case 'G': 868 flag = 'f'; 869 break; 870 case 'd': case 'i': 871 flag = 'd'; 872 if(*(s-1) == 'l') break; 873 *(t-1) = 'l'; 874 *t = 'd'; 875 *++t = '\0'; 876 break; 877 case 'o': case 'x': case 'X': case 'u': 878 flag = *(s-1) == 'l' ? 'd' : 'u'; 879 break; 880 case 's': 881 flag = 's'; 882 break; 883 case 'c': 884 flag = 'c'; 885 break; 886 default: 887 WARNING("weird printf conversion %s", fmt); 888 flag = '?'; 889 break; 890 } 891 if (a == NULL) 892 FATAL("not enough args in printf(%s)", os); 893 x = execute(a); 894 a = a->nnext; 895 n = MAXNUMSIZE; 896 if (fmtwd > n) 897 n = fmtwd; 898 adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5"); 899 switch (flag) { 900 case '?': /* unknown, so dump it too */ 901 snprintf(p, buf + bufsize - p, "%s", fmt); 902 t = getsval(x); 903 n = strlen(t); 904 if (fmtwd > n) 905 n = fmtwd; 906 adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6"); 907 p += strlen(p); 908 snprintf(p, buf + bufsize - p, "%s", t); 909 break; 910 case 'f': snprintf(p, buf + bufsize - p, fmt, getfval(x)); break; 911 case 'd': snprintf(p, buf + bufsize - p, fmt, (long) getfval(x)); break; 912 case 'u': snprintf(p, buf + bufsize - p, fmt, (int) getfval(x)); break; 913 case 's': 914 t = getsval(x); 915 n = strlen(t); 916 if (fmtwd > n) 917 n = fmtwd; 918 if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7")) 919 FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); 920 snprintf(p, buf + bufsize - p, fmt, t); 921 break; 922 case 'c': 923 if (isnum(x)) { 924 if (getfval(x)) 925 snprintf(p, buf + bufsize - p, fmt, (int) getfval(x)); 926 else { 927 *p++ = '\0'; /* explicit null byte */ 928 *p = '\0'; /* next output will start here */ 929 } 930 } else 931 snprintf(p, buf + bufsize - p, fmt, getsval(x)[0]); 932 break; 933 default: 934 FATAL("can't happen: bad conversion %c in format()", flag); 935 } 936 tempfree(x); 937 p += strlen(p); 938 s++; 939 } 940 *p = '\0'; 941 free(fmt); 942 for ( ; a; a = a->nnext) /* evaluate any remaining args */ 943 execute(a); 944 *pbuf = buf; 945 *pbufsize = bufsize; 946 return p - buf; 947 } 948 949 Cell *awksprintf(Node **a, int n) /* sprintf(a[0]) */ 950 { 951 Cell *x; 952 Node *y; 953 char *buf; 954 int bufsz=3*recsize; 955 956 if ((buf = (char *) malloc(bufsz)) == NULL) 957 FATAL("out of memory in awksprintf"); 958 y = a[0]->nnext; 959 x = execute(a[0]); 960 if (format(&buf, &bufsz, getsval(x), y) == -1) 961 FATAL("sprintf string %.30s... too long. can't happen.", buf); 962 tempfree(x); 963 x = gettemp(); 964 x->sval = buf; 965 x->tval = STR; 966 return(x); 967 } 968 969 Cell *awkprintf(Node **a, int n) /* printf */ 970 { /* a[0] is list of args, starting with format string */ 971 /* a[1] is redirection operator, a[2] is redirection file */ 972 FILE *fp; 973 Cell *x; 974 Node *y; 975 char *buf; 976 int len; 977 int bufsz=3*recsize; 978 979 if ((buf = (char *) malloc(bufsz)) == NULL) 980 FATAL("out of memory in awkprintf"); 981 y = a[0]->nnext; 982 x = execute(a[0]); 983 if ((len = format(&buf, &bufsz, getsval(x), y)) == -1) 984 FATAL("printf string %.30s... too long. can't happen.", buf); 985 tempfree(x); 986 if (a[1] == NULL) { 987 /* fputs(buf, stdout); */ 988 fwrite(buf, len, 1, stdout); 989 if (ferror(stdout)) 990 FATAL("write error on stdout"); 991 } else { 992 fp = redirect(ptoi(a[1]), a[2]); 993 /* fputs(buf, fp); */ 994 fwrite(buf, len, 1, fp); 995 fflush(fp); 996 if (ferror(fp)) 997 FATAL("write error on %s", filename(fp)); 998 } 999 free(buf); 1000 return(True); 1001 } 1002 1003 Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */ 1004 { 1005 Awkfloat i, j = 0; 1006 double v; 1007 Cell *x, *y, *z; 1008 1009 x = execute(a[0]); 1010 i = getfval(x); 1011 tempfree(x); 1012 if (n != UMINUS) { 1013 y = execute(a[1]); 1014 j = getfval(y); 1015 tempfree(y); 1016 } 1017 z = gettemp(); 1018 switch (n) { 1019 case ADD: 1020 i += j; 1021 break; 1022 case MINUS: 1023 i -= j; 1024 break; 1025 case MULT: 1026 i *= j; 1027 break; 1028 case DIVIDE: 1029 if (j == 0) 1030 FATAL("division by zero"); 1031 i /= j; 1032 break; 1033 case MOD: 1034 if (j == 0) 1035 FATAL("division by zero in mod"); 1036 modf(i/j, &v); 1037 i = i - j * v; 1038 break; 1039 case UMINUS: 1040 i = -i; 1041 break; 1042 case POWER: 1043 if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */ 1044 i = ipow(i, (int) j); 1045 else 1046 i = errcheck(pow(i, j), "pow"); 1047 break; 1048 default: /* can't happen */ 1049 FATAL("illegal arithmetic operator %d", n); 1050 } 1051 setfval(z, i); 1052 return(z); 1053 } 1054 1055 double ipow(double x, int n) /* x**n. ought to be done by pow, but isn't always */ 1056 { 1057 double v; 1058 1059 if (n <= 0) 1060 return 1; 1061 v = ipow(x, n/2); 1062 if (n % 2 == 0) 1063 return v * v; 1064 else 1065 return x * v * v; 1066 } 1067 1068 Cell *incrdecr(Node **a, int n) /* a[0]++, etc. */ 1069 { 1070 Cell *x, *z; 1071 int k; 1072 Awkfloat xf; 1073 1074 x = execute(a[0]); 1075 xf = getfval(x); 1076 k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 1077 if (n == PREINCR || n == PREDECR) { 1078 setfval(x, xf + k); 1079 return(x); 1080 } 1081 z = gettemp(); 1082 setfval(z, xf); 1083 setfval(x, xf + k); 1084 tempfree(x); 1085 return(z); 1086 } 1087 1088 Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ 1089 { /* this is subtle; don't muck with it. */ 1090 Cell *x, *y; 1091 Awkfloat xf, yf; 1092 double v; 1093 1094 y = execute(a[1]); 1095 x = execute(a[0]); 1096 if (n == ASSIGN) { /* ordinary assignment */ 1097 if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */ 1098 ; /* leave alone unless it's a field */ 1099 else if ((y->tval & (STR|NUM)) == (STR|NUM)) { 1100 setsval(x, getsval(y)); 1101 x->fval = getfval(y); 1102 x->tval |= NUM; 1103 } 1104 else if (isstr(y)) 1105 setsval(x, getsval(y)); 1106 else if (isnum(y)) 1107 setfval(x, getfval(y)); 1108 else 1109 funnyvar(y, "read value of"); 1110 tempfree(y); 1111 return(x); 1112 } 1113 xf = getfval(x); 1114 yf = getfval(y); 1115 switch (n) { 1116 case ADDEQ: 1117 xf += yf; 1118 break; 1119 case SUBEQ: 1120 xf -= yf; 1121 break; 1122 case MULTEQ: 1123 xf *= yf; 1124 break; 1125 case DIVEQ: 1126 if (yf == 0) 1127 FATAL("division by zero in /="); 1128 xf /= yf; 1129 break; 1130 case MODEQ: 1131 if (yf == 0) 1132 FATAL("division by zero in %%="); 1133 modf(xf/yf, &v); 1134 xf = xf - yf * v; 1135 break; 1136 case POWEQ: 1137 if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ 1138 xf = ipow(xf, (int) yf); 1139 else 1140 xf = errcheck(pow(xf, yf), "pow"); 1141 break; 1142 default: 1143 FATAL("illegal assignment operator %d", n); 1144 break; 1145 } 1146 tempfree(y); 1147 setfval(x, xf); 1148 return(x); 1149 } 1150 1151 Cell *cat(Node **a, int q) /* a[0] cat a[1] */ 1152 { 1153 Cell *x, *y, *z; 1154 int n1, n2; 1155 char *s; 1156 size_t len; 1157 1158 x = execute(a[0]); 1159 y = execute(a[1]); 1160 getsval(x); 1161 getsval(y); 1162 n1 = strlen(x->sval); 1163 n2 = strlen(y->sval); 1164 len = n1 + n2 + 1; 1165 s = (char *) malloc(len); 1166 if (s == NULL) 1167 FATAL("out of space concatenating %.15s... and %.15s...", 1168 x->sval, y->sval); 1169 strlcpy(s, x->sval, len); 1170 strlcpy(s+n1, y->sval, len - n1); 1171 tempfree(x); 1172 tempfree(y); 1173 z = gettemp(); 1174 z->sval = s; 1175 z->tval = STR; 1176 return(z); 1177 } 1178 1179 Cell *pastat(Node **a, int n) /* a[0] { a[1] } */ 1180 { 1181 Cell *x; 1182 1183 if (a[0] == 0) 1184 x = execute(a[1]); 1185 else { 1186 x = execute(a[0]); 1187 if (istrue(x)) { 1188 tempfree(x); 1189 x = execute(a[1]); 1190 } 1191 } 1192 return x; 1193 } 1194 1195 Cell *dopa2(Node **a, int n) /* a[0], a[1] { a[2] } */ 1196 { 1197 Cell *x; 1198 int pair; 1199 1200 pair = ptoi(a[3]); 1201 if (pairstack[pair] == 0) { 1202 x = execute(a[0]); 1203 if (istrue(x)) 1204 pairstack[pair] = 1; 1205 tempfree(x); 1206 } 1207 if (pairstack[pair] == 1) { 1208 x = execute(a[1]); 1209 if (istrue(x)) 1210 pairstack[pair] = 0; 1211 tempfree(x); 1212 x = execute(a[2]); 1213 return(x); 1214 } 1215 return(False); 1216 } 1217 1218 Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ 1219 { 1220 Cell *x = 0, *y, *ap; 1221 char *s; 1222 int sep; 1223 char *t, temp, num[50], *fs = 0; 1224 int n, tempstat, arg3type; 1225 1226 y = execute(a[0]); /* source string */ 1227 s = getsval(y); 1228 arg3type = ptoi(a[3]); 1229 if (a[2] == 0) /* fs string */ 1230 fs = *FS; 1231 else if (arg3type == STRING) { /* split(str,arr,"string") */ 1232 x = execute(a[2]); 1233 fs = getsval(x); 1234 } else if (arg3type == REGEXPR) 1235 fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ 1236 else 1237 FATAL("illegal type of split"); 1238 sep = *fs; 1239 ap = execute(a[1]); /* array name */ 1240 freesymtab(ap); 1241 dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); 1242 ap->tval &= ~STR; 1243 ap->tval |= ARR; 1244 ap->sval = (char *) makesymtab(NSYMTAB); 1245 1246 n = 0; 1247 if (arg3type == REGEXPR && strlen((char*)((fa*)a[2])->restr) == 0) { 1248 /* split(s, a, //); have to arrange that it looks like empty sep */ 1249 arg3type = 0; 1250 fs = ""; 1251 sep = 0; 1252 } 1253 if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */ 1254 fa *pfa; 1255 if (arg3type == REGEXPR) { /* it's ready already */ 1256 pfa = (fa *) a[2]; 1257 } else { 1258 pfa = makedfa(fs, 1); 1259 } 1260 if (nematch(pfa,s)) { 1261 tempstat = pfa->initstat; 1262 pfa->initstat = 2; 1263 do { 1264 n++; 1265 snprintf(num, sizeof num, "%d", n); 1266 temp = *patbeg; 1267 *patbeg = '\0'; 1268 if (is_number(s)) 1269 setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); 1270 else 1271 setsymtab(num, s, 0.0, STR, (Array *) ap->sval); 1272 *patbeg = temp; 1273 s = patbeg + patlen; 1274 if (*(patbeg+patlen-1) == 0 || *s == 0) { 1275 n++; 1276 snprintf(num, sizeof num, "%d", n); 1277 setsymtab(num, "", 0.0, STR, (Array *) ap->sval); 1278 pfa->initstat = tempstat; 1279 goto spdone; 1280 } 1281 } while (nematch(pfa,s)); 1282 pfa->initstat = tempstat; /* bwk: has to be here to reset */ 1283 /* cf gsub and refldbld */ 1284 } 1285 n++; 1286 snprintf(num, sizeof num, "%d", n); 1287 if (is_number(s)) 1288 setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); 1289 else 1290 setsymtab(num, s, 0.0, STR, (Array *) ap->sval); 1291 spdone: 1292 pfa = NULL; 1293 } else if (sep == ' ') { 1294 for (n = 0; ; ) { 1295 while (*s == ' ' || *s == '\t' || *s == '\n') 1296 s++; 1297 if (*s == 0) 1298 break; 1299 n++; 1300 t = s; 1301 do 1302 s++; 1303 while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); 1304 temp = *s; 1305 *s = '\0'; 1306 snprintf(num, sizeof num, "%d", n); 1307 if (is_number(t)) 1308 setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); 1309 else 1310 setsymtab(num, t, 0.0, STR, (Array *) ap->sval); 1311 *s = temp; 1312 if (*s != 0) 1313 s++; 1314 } 1315 } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ 1316 for (n = 0; *s != 0; s++) { 1317 char buf[2]; 1318 n++; 1319 snprintf(num, sizeof num, "%d", n); 1320 buf[0] = *s; 1321 buf[1] = 0; 1322 if (isdigit((uschar)buf[0])) 1323 setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); 1324 else 1325 setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); 1326 } 1327 } else if (*s != 0) { 1328 for (;;) { 1329 n++; 1330 t = s; 1331 while (*s != sep && *s != '\n' && *s != '\0') 1332 s++; 1333 temp = *s; 1334 *s = '\0'; 1335 snprintf(num, sizeof num, "%d", n); 1336 if (is_number(t)) 1337 setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); 1338 else 1339 setsymtab(num, t, 0.0, STR, (Array *) ap->sval); 1340 *s = temp; 1341 if (*s++ == 0) 1342 break; 1343 } 1344 } 1345 tempfree(ap); 1346 tempfree(y); 1347 if (a[2] != 0 && arg3type == STRING) { 1348 tempfree(x); 1349 } 1350 x = gettemp(); 1351 x->tval = NUM; 1352 x->fval = n; 1353 return(x); 1354 } 1355 1356 Cell *condexpr(Node **a, int n) /* a[0] ? a[1] : a[2] */ 1357 { 1358 Cell *x; 1359 1360 x = execute(a[0]); 1361 if (istrue(x)) { 1362 tempfree(x); 1363 x = execute(a[1]); 1364 } else { 1365 tempfree(x); 1366 x = execute(a[2]); 1367 } 1368 return(x); 1369 } 1370 1371 Cell *ifstat(Node **a, int n) /* if (a[0]) a[1]; else a[2] */ 1372 { 1373 Cell *x; 1374 1375 x = execute(a[0]); 1376 if (istrue(x)) { 1377 tempfree(x); 1378 x = execute(a[1]); 1379 } else if (a[2] != 0) { 1380 tempfree(x); 1381 x = execute(a[2]); 1382 } 1383 return(x); 1384 } 1385 1386 Cell *whilestat(Node **a, int n) /* while (a[0]) a[1] */ 1387 { 1388 Cell *x; 1389 1390 for (;;) { 1391 x = execute(a[0]); 1392 if (!istrue(x)) 1393 return(x); 1394 tempfree(x); 1395 x = execute(a[1]); 1396 if (isbreak(x)) { 1397 x = True; 1398 return(x); 1399 } 1400 if (isnext(x) || isexit(x) || isret(x)) 1401 return(x); 1402 tempfree(x); 1403 } 1404 } 1405 1406 Cell *dostat(Node **a, int n) /* do a[0]; while(a[1]) */ 1407 { 1408 Cell *x; 1409 1410 for (;;) { 1411 x = execute(a[0]); 1412 if (isbreak(x)) 1413 return True; 1414 if (isnext(x) || isexit(x) || isret(x)) 1415 return(x); 1416 tempfree(x); 1417 x = execute(a[1]); 1418 if (!istrue(x)) 1419 return(x); 1420 tempfree(x); 1421 } 1422 } 1423 1424 Cell *forstat(Node **a, int n) /* for (a[0]; a[1]; a[2]) a[3] */ 1425 { 1426 Cell *x; 1427 1428 x = execute(a[0]); 1429 tempfree(x); 1430 for (;;) { 1431 if (a[1]!=0) { 1432 x = execute(a[1]); 1433 if (!istrue(x)) return(x); 1434 else tempfree(x); 1435 } 1436 x = execute(a[3]); 1437 if (isbreak(x)) /* turn off break */ 1438 return True; 1439 if (isnext(x) || isexit(x) || isret(x)) 1440 return(x); 1441 tempfree(x); 1442 x = execute(a[2]); 1443 tempfree(x); 1444 } 1445 } 1446 1447 Cell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */ 1448 { 1449 Cell *x, *vp, *arrayp, *cp, *ncp; 1450 Array *tp; 1451 int i; 1452 1453 vp = execute(a[0]); 1454 arrayp = execute(a[1]); 1455 if (!isarr(arrayp)) { 1456 return True; 1457 } 1458 tp = (Array *) arrayp->sval; 1459 tempfree(arrayp); 1460 for (i = 0; i < tp->size; i++) { /* this routine knows too much */ 1461 for (cp = tp->tab[i]; cp != NULL; cp = ncp) { 1462 setsval(vp, cp->nval); 1463 ncp = cp->cnext; 1464 x = execute(a[2]); 1465 if (isbreak(x)) { 1466 tempfree(vp); 1467 return True; 1468 } 1469 if (isnext(x) || isexit(x) || isret(x)) { 1470 tempfree(vp); 1471 return(x); 1472 } 1473 tempfree(x); 1474 } 1475 } 1476 return True; 1477 } 1478 1479 Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ 1480 { 1481 Cell *x, *y; 1482 Awkfloat u; 1483 int t; 1484 Awkfloat tmp; 1485 char *p, *buf; 1486 Node *nextarg; 1487 FILE *fp; 1488 1489 t = ptoi(a[0]); 1490 x = execute(a[1]); 1491 nextarg = a[1]->nnext; 1492 switch (t) { 1493 case FLENGTH: 1494 if (isarr(x)) 1495 u = ((Array *) x->sval)->nelem; /* GROT. should be function*/ 1496 else 1497 u = strlen(getsval(x)); 1498 break; 1499 case FLOG: 1500 u = errcheck(log(getfval(x)), "log"); break; 1501 case FINT: 1502 modf(getfval(x), &u); break; 1503 case FEXP: 1504 u = errcheck(exp(getfval(x)), "exp"); break; 1505 case FSQRT: 1506 u = errcheck(sqrt(getfval(x)), "sqrt"); break; 1507 case FSIN: 1508 u = sin(getfval(x)); break; 1509 case FCOS: 1510 u = cos(getfval(x)); break; 1511 case FATAN: 1512 if (nextarg == 0) { 1513 WARNING("atan2 requires two arguments; returning 1.0"); 1514 u = 1.0; 1515 } else { 1516 y = execute(a[1]->nnext); 1517 u = atan2(getfval(x), getfval(y)); 1518 tempfree(y); 1519 nextarg = nextarg->nnext; 1520 } 1521 break; 1522 case FCOMPL: 1523 u = ~((int)getfval(x)); 1524 break; 1525 case FAND: 1526 if (nextarg == 0) { 1527 WARNING("and requires two arguments; returning 0"); 1528 u = 0; 1529 break; 1530 } 1531 y = execute(a[1]->nnext); 1532 u = ((int)getfval(x)) & ((int)getfval(y)); 1533 tempfree(y); 1534 nextarg = nextarg->nnext; 1535 break; 1536 case FFOR: 1537 if (nextarg == 0) { 1538 WARNING("or requires two arguments; returning 0"); 1539 u = 0; 1540 break; 1541 } 1542 y = execute(a[1]->nnext); 1543 u = ((int)getfval(x)) | ((int)getfval(y)); 1544 tempfree(y); 1545 nextarg = nextarg->nnext; 1546 break; 1547 case FXOR: 1548 if (nextarg == 0) { 1549 WARNING("or requires two arguments; returning 0"); 1550 u = 0; 1551 break; 1552 } 1553 y = execute(a[1]->nnext); 1554 u = ((int)getfval(x)) ^ ((int)getfval(y)); 1555 tempfree(y); 1556 nextarg = nextarg->nnext; 1557 break; 1558 case FLSHIFT: 1559 if (nextarg == 0) { 1560 WARNING("or requires two arguments; returning 0"); 1561 u = 0; 1562 break; 1563 } 1564 y = execute(a[1]->nnext); 1565 u = ((int)getfval(x)) << ((int)getfval(y)); 1566 tempfree(y); 1567 nextarg = nextarg->nnext; 1568 break; 1569 case FRSHIFT: 1570 if (nextarg == 0) { 1571 WARNING("or requires two arguments; returning 0"); 1572 u = 0; 1573 break; 1574 } 1575 y = execute(a[1]->nnext); 1576 u = ((int)getfval(x)) >> ((int)getfval(y)); 1577 tempfree(y); 1578 nextarg = nextarg->nnext; 1579 break; 1580 case FSYSTEM: 1581 fflush(stdout); /* in case something is buffered already */ 1582 u = (Awkfloat) system(getsval(x)) / 256; /* 256 is unix-dep */ 1583 break; 1584 case FRAND: 1585 if (use_srandom) 1586 u = (Awkfloat) (random() % RAND_MAX) / RAND_MAX; 1587 else 1588 u = (Awkfloat)arc4random() / 0xffffffff; 1589 break; 1590 case FSRAND: 1591 if (isrec(x)) /* no argument provided, want arc4random() */ 1592 use_srandom = 0; 1593 else { 1594 use_srandom = 1; 1595 u = getfval(x); 1596 tmp = u; 1597 srandom((unsigned int) u); 1598 u = srand_seed; 1599 srand_seed = tmp; 1600 } 1601 break; 1602 case FTOUPPER: 1603 case FTOLOWER: 1604 buf = tostring(getsval(x)); 1605 if (t == FTOUPPER) { 1606 for (p = buf; *p; p++) 1607 if (islower((uschar) *p)) 1608 *p = toupper((uschar)*p); 1609 } else { 1610 for (p = buf; *p; p++) 1611 if (isupper((uschar) *p)) 1612 *p = tolower((uschar)*p); 1613 } 1614 tempfree(x); 1615 x = gettemp(); 1616 setsval(x, buf); 1617 free(buf); 1618 return x; 1619 case FFLUSH: 1620 if (isrec(x) || strlen(getsval(x)) == 0) { 1621 flush_all(); /* fflush() or fflush("") -> all */ 1622 u = 0; 1623 } else if ((fp = openfile(FFLUSH, getsval(x))) == NULL) 1624 u = EOF; 1625 else 1626 u = fflush(fp); 1627 break; 1628 default: /* can't happen */ 1629 FATAL("illegal function type %d", t); 1630 break; 1631 } 1632 tempfree(x); 1633 x = gettemp(); 1634 setfval(x, u); 1635 if (nextarg != 0) { 1636 WARNING("warning: function has too many arguments"); 1637 for ( ; nextarg; nextarg = nextarg->nnext) 1638 execute(nextarg); 1639 } 1640 return(x); 1641 } 1642 1643 Cell *printstat(Node **a, int n) /* print a[0] */ 1644 { 1645 Node *x; 1646 Cell *y; 1647 FILE *fp; 1648 1649 if (a[1] == 0) /* a[1] is redirection operator, a[2] is file */ 1650 fp = stdout; 1651 else 1652 fp = redirect(ptoi(a[1]), a[2]); 1653 for (x = a[0]; x != NULL; x = x->nnext) { 1654 y = execute(x); 1655 fputs(getpssval(y), fp); 1656 tempfree(y); 1657 if (x->nnext == NULL) 1658 fputs(*ORS, fp); 1659 else 1660 fputs(*OFS, fp); 1661 } 1662 if (a[1] != 0) 1663 fflush(fp); 1664 if (ferror(fp)) 1665 FATAL("write error on %s", filename(fp)); 1666 return(True); 1667 } 1668 1669 Cell *nullproc(Node **a, int n) 1670 { 1671 n = n; 1672 a = a; 1673 return 0; 1674 } 1675 1676 1677 FILE *redirect(int a, Node *b) /* set up all i/o redirections */ 1678 { 1679 FILE *fp; 1680 Cell *x; 1681 char *fname; 1682 1683 x = execute(b); 1684 fname = getsval(x); 1685 fp = openfile(a, fname); 1686 if (fp == NULL) 1687 FATAL("can't open file %s", fname); 1688 tempfree(x); 1689 return fp; 1690 } 1691 1692 struct files { 1693 FILE *fp; 1694 const char *fname; 1695 int mode; /* '|', 'a', 'w' => LE/LT, GT */ 1696 } *files; 1697 1698 int nfiles; 1699 1700 void stdinit(void) /* in case stdin, etc., are not constants */ 1701 { 1702 nfiles = FOPEN_MAX; 1703 files = calloc(nfiles, sizeof(*files)); 1704 if (files == NULL) 1705 FATAL("can't allocate file memory for %u files", nfiles); 1706 files[0].fp = stdin; 1707 files[0].fname = "/dev/stdin"; 1708 files[0].mode = LT; 1709 files[1].fp = stdout; 1710 files[1].fname = "/dev/stdout"; 1711 files[1].mode = GT; 1712 files[2].fp = stderr; 1713 files[2].fname = "/dev/stderr"; 1714 files[2].mode = GT; 1715 } 1716 1717 FILE *openfile(int a, const char *us) 1718 { 1719 const char *s = us; 1720 int i, m; 1721 FILE *fp = 0; 1722 1723 if (*s == '\0') 1724 FATAL("null file name in print or getline"); 1725 for (i=0; i < nfiles; i++) 1726 if (files[i].fname && strcmp(s, files[i].fname) == 0) { 1727 if (a == files[i].mode || (a==APPEND && files[i].mode==GT)) 1728 return files[i].fp; 1729 if (a == FFLUSH) 1730 return files[i].fp; 1731 } 1732 if (a == FFLUSH) /* didn't find it, so don't create it! */ 1733 return NULL; 1734 1735 for (i=0; i < nfiles; i++) 1736 if (files[i].fp == 0) 1737 break; 1738 if (i >= nfiles) { 1739 struct files *nf; 1740 int nnf = nfiles + FOPEN_MAX; 1741 nf = realloc(files, nnf * sizeof(*nf)); 1742 if (nf == NULL) 1743 FATAL("cannot grow files for %s and %d files", s, nnf); 1744 memset(&nf[nfiles], 0, FOPEN_MAX * sizeof(*nf)); 1745 nfiles = nnf; 1746 files = nf; 1747 } 1748 fflush(stdout); /* force a semblance of order */ 1749 m = a; 1750 if (a == GT) { 1751 fp = fopen(s, "w"); 1752 } else if (a == APPEND) { 1753 fp = fopen(s, "a"); 1754 m = GT; /* so can mix > and >> */ 1755 } else if (a == '|') { /* output pipe */ 1756 fp = popen(s, "w"); 1757 } else if (a == LE) { /* input pipe */ 1758 fp = popen(s, "r"); 1759 } else if (a == LT) { /* getline <file */ 1760 fp = strcmp(s, "-") == 0 ? stdin : fopen(s, "r"); /* "-" is stdin */ 1761 } else /* can't happen */ 1762 FATAL("illegal redirection %d", a); 1763 if (fp != NULL) { 1764 files[i].fname = tostring(s); 1765 files[i].fp = fp; 1766 files[i].mode = m; 1767 } 1768 return fp; 1769 } 1770 1771 const char *filename(FILE *fp) 1772 { 1773 int i; 1774 1775 for (i = 0; i < nfiles; i++) 1776 if (fp == files[i].fp) 1777 return files[i].fname; 1778 return "???"; 1779 } 1780 1781 Cell *closefile(Node **a, int n) 1782 { 1783 Cell *x; 1784 int i, stat; 1785 1786 n = n; 1787 x = execute(a[0]); 1788 getsval(x); 1789 stat = -1; 1790 for (i = 0; i < nfiles; i++) { 1791 if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) { 1792 if (ferror(files[i].fp)) 1793 WARNING( "i/o error occurred on %s", files[i].fname ); 1794 if (files[i].mode == '|' || files[i].mode == LE) 1795 stat = pclose(files[i].fp); 1796 else 1797 stat = fclose(files[i].fp); 1798 if (stat == EOF) 1799 WARNING( "i/o error occurred closing %s", files[i].fname ); 1800 if (i > 2) /* don't do /dev/std... */ 1801 xfree(files[i].fname); 1802 files[i].fname = NULL; /* watch out for ref thru this */ 1803 files[i].fp = NULL; 1804 } 1805 } 1806 tempfree(x); 1807 x = gettemp(); 1808 setfval(x, (Awkfloat) stat); 1809 return(x); 1810 } 1811 1812 void closeall(void) 1813 { 1814 int i, stat; 1815 1816 for (i = 0; i < FOPEN_MAX; i++) { 1817 if (files[i].fp) { 1818 if (ferror(files[i].fp)) 1819 WARNING( "i/o error occurred on %s", files[i].fname ); 1820 if (files[i].mode == '|' || files[i].mode == LE) 1821 stat = pclose(files[i].fp); 1822 else 1823 stat = fclose(files[i].fp); 1824 if (stat == EOF) 1825 WARNING( "i/o error occurred while closing %s", files[i].fname ); 1826 } 1827 } 1828 } 1829 1830 void flush_all(void) 1831 { 1832 int i; 1833 1834 for (i = 0; i < nfiles; i++) 1835 if (files[i].fp) 1836 fflush(files[i].fp); 1837 } 1838 1839 void backsub(char **pb_ptr, char **sptr_ptr); 1840 1841 Cell *sub(Node **a, int nnn) /* substitute command */ 1842 { 1843 char *sptr, *pb, *q; 1844 Cell *x, *y, *result; 1845 char *t, *buf; 1846 fa *pfa; 1847 int bufsz = recsize; 1848 1849 if ((buf = (char *) malloc(bufsz)) == NULL) 1850 FATAL("out of memory in sub"); 1851 x = execute(a[3]); /* target string */ 1852 t = getsval(x); 1853 if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ 1854 pfa = (fa *) a[1]; /* regular expression */ 1855 else { 1856 y = execute(a[1]); 1857 pfa = makedfa(getsval(y), 1); 1858 tempfree(y); 1859 } 1860 y = execute(a[2]); /* replacement string */ 1861 result = False; 1862 if (pmatch(pfa, t)) { 1863 sptr = t; 1864 adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); 1865 pb = buf; 1866 while (sptr < patbeg) 1867 *pb++ = *sptr++; 1868 sptr = getsval(y); 1869 while (*sptr != 0) { 1870 adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub"); 1871 if (*sptr == '\\') { 1872 backsub(&pb, &sptr); 1873 } else if (*sptr == '&') { 1874 sptr++; 1875 adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub"); 1876 for (q = patbeg; q < patbeg+patlen; ) 1877 *pb++ = *q++; 1878 } else 1879 *pb++ = *sptr++; 1880 } 1881 *pb = '\0'; 1882 if (pb > buf + bufsz) 1883 FATAL("sub result1 %.30s too big; can't happen", buf); 1884 sptr = patbeg + patlen; 1885 if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { 1886 adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub"); 1887 while ((*pb++ = *sptr++) != 0) 1888 ; 1889 } 1890 if (pb > buf + bufsz) 1891 FATAL("sub result2 %.30s too big; can't happen", buf); 1892 setsval(x, buf); /* BUG: should be able to avoid copy */ 1893 result = True; 1894 } 1895 tempfree(x); 1896 tempfree(y); 1897 free(buf); 1898 return result; 1899 } 1900 1901 Cell *gsub(Node **a, int nnn) /* global substitute */ 1902 { 1903 Cell *x, *y; 1904 char *rptr, *sptr, *t, *pb, *q; 1905 char *buf; 1906 fa *pfa; 1907 int mflag, tempstat, num; 1908 int bufsz = recsize; 1909 1910 if ((buf = (char *) malloc(bufsz)) == NULL) 1911 FATAL("out of memory in gsub"); 1912 mflag = 0; /* if mflag == 0, can replace empty string */ 1913 num = 0; 1914 x = execute(a[3]); /* target string */ 1915 t = getsval(x); 1916 if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ 1917 pfa = (fa *) a[1]; /* regular expression */ 1918 else { 1919 y = execute(a[1]); 1920 pfa = makedfa(getsval(y), 1); 1921 tempfree(y); 1922 } 1923 y = execute(a[2]); /* replacement string */ 1924 if (pmatch(pfa, t)) { 1925 tempstat = pfa->initstat; 1926 pfa->initstat = 2; 1927 pb = buf; 1928 rptr = getsval(y); 1929 do { 1930 if (patlen == 0 && *patbeg != 0) { /* matched empty string */ 1931 if (mflag == 0) { /* can replace empty */ 1932 num++; 1933 sptr = rptr; 1934 while (*sptr != 0) { 1935 adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); 1936 if (*sptr == '\\') { 1937 backsub(&pb, &sptr); 1938 } else if (*sptr == '&') { 1939 sptr++; 1940 adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); 1941 for (q = patbeg; q < patbeg+patlen; ) 1942 *pb++ = *q++; 1943 } else 1944 *pb++ = *sptr++; 1945 } 1946 } 1947 if (*t == 0) /* at end */ 1948 goto done; 1949 adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub"); 1950 *pb++ = *t++; 1951 if (pb > buf + bufsz) /* BUG: not sure of this test */ 1952 FATAL("gsub result0 %.30s too big; can't happen", buf); 1953 mflag = 0; 1954 } 1955 else { /* matched nonempty string */ 1956 num++; 1957 sptr = t; 1958 adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub"); 1959 while (sptr < patbeg) 1960 *pb++ = *sptr++; 1961 sptr = rptr; 1962 while (*sptr != 0) { 1963 adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); 1964 if (*sptr == '\\') { 1965 backsub(&pb, &sptr); 1966 } else if (*sptr == '&') { 1967 sptr++; 1968 adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); 1969 for (q = patbeg; q < patbeg+patlen; ) 1970 *pb++ = *q++; 1971 } else 1972 *pb++ = *sptr++; 1973 } 1974 t = patbeg + patlen; 1975 if (patlen == 0 || *t == 0 || *(t-1) == 0) 1976 goto done; 1977 if (pb > buf + bufsz) 1978 FATAL("gsub result1 %.30s too big; can't happen", buf); 1979 mflag = 1; 1980 } 1981 } while (pmatch(pfa,t)); 1982 sptr = t; 1983 adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); 1984 while ((*pb++ = *sptr++) != 0) 1985 ; 1986 done: if (pb < buf + bufsz) 1987 *pb = '\0'; 1988 else if (*(pb-1) != '\0') 1989 FATAL("gsub result2 %.30s truncated; can't happen", buf); 1990 setsval(x, buf); /* BUG: should be able to avoid copy + free */ 1991 pfa->initstat = tempstat; 1992 } 1993 tempfree(x); 1994 tempfree(y); 1995 x = gettemp(); 1996 x->tval = NUM; 1997 x->fval = num; 1998 free(buf); 1999 return(x); 2000 } 2001 2002 void backsub(char **pb_ptr, char **sptr_ptr) /* handle \\& variations */ 2003 { /* sptr[0] == '\\' */ 2004 char *pb = *pb_ptr, *sptr = *sptr_ptr; 2005 2006 if (sptr[1] == '\\') { 2007 if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ 2008 *pb++ = '\\'; 2009 *pb++ = '&'; 2010 sptr += 4; 2011 } else if (sptr[2] == '&') { /* \\& -> \ + matched */ 2012 *pb++ = '\\'; 2013 sptr += 2; 2014 } else { /* \\x -> \\x */ 2015 *pb++ = *sptr++; 2016 *pb++ = *sptr++; 2017 } 2018 } else if (sptr[1] == '&') { /* literal & */ 2019 sptr++; 2020 *pb++ = *sptr++; 2021 } else /* literal \ */ 2022 *pb++ = *sptr++; 2023 2024 *pb_ptr = pb; 2025 *sptr_ptr = sptr; 2026 } 2027