|
|
1.1 ! root 1: #define tempfree(x) if (istemp(x)) tfree(x); else ! 2: ! 3: #define execute(p) (isvalue(p) ? (Cell *)((p)->narg[0]) : real_execute(p)) ! 4: /* #define execute(p) real_execute(p) */ ! 5: ! 6: #define DEBUG ! 7: #include "awk.h" ! 8: #include <math.h> ! 9: #include "y.tab.h" ! 10: #include <stdio.h> ! 11: #include <ctype.h> ! 12: ! 13: #define getfval(p) (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : real_getfval(p)) ! 14: #define getsval(p) (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : real_getsval(p)) ! 15: ! 16: extern Awkfloat real_getfval(); ! 17: extern char *real_getsval(); ! 18: extern Cell *real_execute(), *fieldel(), *dopa2(), *gettemp(), *copycell(); ! 19: extern FILE *openfile(), *redirect(); ! 20: extern fa *makedfa(); ! 21: extern double errcheck(); ! 22: ! 23: #define PA2NUM 29 ! 24: int pairstack[PA2NUM], paircnt; ! 25: Node *winner = NULL; ! 26: Cell *tmps; ! 27: ! 28: static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; ! 29: Cell *true = &truecell; ! 30: static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; ! 31: Cell *false = &falsecell; ! 32: static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; ! 33: Cell *jbreak = &breakcell; ! 34: static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; ! 35: Cell *jcont = &contcell; ! 36: static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM }; ! 37: Cell *jnext = &nextcell; ! 38: static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM }; ! 39: Cell *jexit = &exitcell; ! 40: static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM }; ! 41: Cell *jret = &retcell; ! 42: static Cell tempcell ={ OCELL, CTEMP, 0, 0, 0.0, NUM }; ! 43: ! 44: Node *curnode = NULL; /* the node being executed, for debugging */ ! 45: ! 46: run(a) Node *a; ! 47: { ! 48: execute(a); ! 49: closeall(); ! 50: } ! 51: ! 52: Cell *real_execute(u) Node *u; ! 53: { ! 54: register Cell *(*proc)(); ! 55: register Cell *x; ! 56: register Node *a; ! 57: ! 58: if (u == NULL) ! 59: return(true); ! 60: for (a = u; ; a = a->nnext) { ! 61: curnode = a; ! 62: if (isvalue(a) || a->ntype == NFIELD) { ! 63: x = (Cell *) (a->narg[0]); ! 64: x->ctype = OCELL; ! 65: if ((x->tval & FLD) && !donefld) ! 66: fldbld(); ! 67: else if ((x->tval & REC) && !donerec) ! 68: recbld(); ! 69: return(x); ! 70: } ! 71: if (notlegal(a->nobj)) /* probably a Cell* but too risky to print */ ! 72: error(FATAL, "illegal statement"); ! 73: proc = proctab[a->nobj-FIRSTTOKEN]; ! 74: x = (*proc)(a->narg, a->nobj); ! 75: if ((x->tval & FLD) && !donefld) ! 76: fldbld(); ! 77: else if ((x->tval & REC) && !donerec) ! 78: recbld(); ! 79: if (isexpr(a)) ! 80: return(x); ! 81: /* a statement, goto next statement */ ! 82: if (isjump(x)) ! 83: return(x); ! 84: if (a->nnext == (Node *)NULL) ! 85: return(x); ! 86: tempfree(x); ! 87: } ! 88: } ! 89: ! 90: Cell *program(a, n) register Node **a; ! 91: { ! 92: register Cell *x; ! 93: ! 94: if (a[0] != NULL) { /* BEGIN */ ! 95: x = execute(a[0]); ! 96: if (isexit(x)) ! 97: return(true); ! 98: if (isjump(x)) ! 99: error(FATAL, "unexpected break, continue or next"); ! 100: tempfree(x); ! 101: } ! 102: loop: ! 103: while (getrec(record) > 0) { ! 104: x = execute(a[1]); ! 105: if (isexit(x)) ! 106: break; ! 107: tempfree(x); ! 108: } ! 109: if (a[2] != NULL) { /* END */ ! 110: x = execute(a[2]); ! 111: if (iscont(x)) /* read some more */ ! 112: goto loop; ! 113: if (isbreak(x) || isnext(x)) ! 114: error(FATAL, "unexpected break or next"); ! 115: tempfree(x); ! 116: } ! 117: return(true); ! 118: } ! 119: ! 120: #define FRAME 100 ! 121: struct Frame { ! 122: int nargs; /* number of arguments in this call */ ! 123: Cell *fcncell; /* pointer to Cell for function */ ! 124: Cell **args; /* pointer to array of arguments after execute */ ! 125: Cell *retval; /* return value */ ! 126: } frame[FRAME]; ! 127: ! 128: struct Frame *fp = frame; /* frame pointer. bottom level unused */ ! 129: ! 130: Cell *call(a, n) Node **a; ! 131: { ! 132: int i, ncall, ndef; ! 133: Node *x; ! 134: Cell **args, *y, *z, *fcn; ! 135: char *s; ! 136: ! 137: fcn = execute(a[0]); /* the function itself */ ! 138: s = fcn->nval; ! 139: if (!isfunc(fcn)) ! 140: error(FATAL, "calling undefined function %s", s); ! 141: for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ ! 142: ncall++; ! 143: ndef = (int) fcn->fval; /* args in defn */ ! 144: dprintf("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame); ! 145: args = (Cell **) Calloc(ndef>ncall ? ndef : ncall, sizeof (Cell *)); ! 146: for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ ! 147: dprintf("evaluate args[%d], fp=%d:\n", i, fp-frame); ! 148: y = execute(x); ! 149: dprintf("args[%d]: %s %f <%s>, t=%o\n", ! 150: i, y->nval, getfval(y), getsval(y), y->tval); ! 151: if (!isarr(y)) { ! 152: args[i] = copycell(y); ! 153: } else { ! 154: args[i] = y; /* arrays by ref */ ! 155: } ! 156: tempfree(y); ! 157: } ! 158: for ( ; i < ndef; i++) { /* add null args for ones not provided */ ! 159: args[i] = gettemp(); ! 160: args[i]->sval = ""; ! 161: args[i]->tval = STR|NUM|DONTFREE; ! 162: args[i]->csub = CCOPY; ! 163: } ! 164: fp++; /* now ok to up frame */ ! 165: if (fp >= frame+FRAME) ! 166: error(FATAL, "function %s nested too deeply", s); ! 167: fp->fcncell = fcn; ! 168: fp->args = args; ! 169: fp->nargs = ndef; /* number defined with (can be more than call) */ ! 170: fp->retval = gettemp(); ! 171: ! 172: dprintf("start exec of %s, fp=%d\n", s, fp-frame); ! 173: y = execute((Node *)(fcn->sval)); /* execute body */ ! 174: dprintf("finished exec of %s, fp=%d\n", s, fp-frame); ! 175: ! 176: for (i = 0; i < ndef; i++) { ! 177: Cell *t = fp->args[i]; ! 178: if (t->csub == CCOPY) { ! 179: if (isarr(t)) ! 180: freesymtab(t); ! 181: t->csub = CTEMP; ! 182: } ! 183: tempfree(t); ! 184: } ! 185: if (isexit(y) || isnext(y)) ! 186: return y; ! 187: z = fp->retval; /* return value */ ! 188: dprintf("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval); ! 189: xfree(fp->args); ! 190: fp--; ! 191: tempfree(fcn); ! 192: return(z); ! 193: } ! 194: ! 195: Cell *copycell(x) /* make a copy of a cell in a temp */ ! 196: Cell *x; ! 197: { ! 198: Cell *y; ! 199: ! 200: y = gettemp(); ! 201: y->csub = CCOPY; /* prevents freeing until call is over */ ! 202: y->nval = x->nval; ! 203: y->sval = x->sval ? tostring(x->sval) : NULL; ! 204: y->fval = x->fval; ! 205: y->tval = x->tval & ~CON; /* copy is not a constant */ ! 206: return y; ! 207: } ! 208: ! 209: Cell *arg(a,n) Node **a; ! 210: { ! 211: int n; ! 212: ! 213: n = (int) a[0]; /* argument number, counting from 0 */ ! 214: dprintf("arg(%d), fp->nargs=%d\n", n, fp->nargs); ! 215: if (n+1 > fp->nargs) ! 216: error(FATAL, "argument #%d of function %s was not supplied", ! 217: n+1, fp->fcncell->nval); ! 218: return fp->args[n]; ! 219: } ! 220: ! 221: Cell *jump(a, n) Node **a; ! 222: { ! 223: register Cell *y; ! 224: ! 225: switch (n) { ! 226: case EXIT: ! 227: if (a[0] != NULL) { ! 228: y = execute(a[0]); ! 229: errorflag = getfval(y); ! 230: tempfree(y); ! 231: } ! 232: return(jexit); ! 233: case RETURN: ! 234: if (a[0] != NULL) { ! 235: y = execute(a[0]); ! 236: if ((y->tval & (STR|NUM)) == (STR|NUM)) { ! 237: setsval(fp->retval, getsval(y)); ! 238: fp->retval->fval = getfval(y); ! 239: fp->retval->tval |= NUM; ! 240: } ! 241: else if (y->tval & STR) ! 242: setsval(fp->retval, getsval(y)); ! 243: else if (y->tval & NUM) ! 244: setfval(fp->retval, getfval(y)); ! 245: tempfree(y); ! 246: } ! 247: return(jret); ! 248: case NEXT: ! 249: return(jnext); ! 250: case BREAK: ! 251: return(jbreak); ! 252: case CONTINUE: ! 253: return(jcont); ! 254: default: ! 255: error(FATAL, "illegal jump type %d", n); ! 256: } ! 257: } ! 258: ! 259: Cell *getline(a, n) Node **a; int n; ! 260: { ! 261: /* a[0] is variable, a[1] is operator, a[2] is filename */ ! 262: register Cell *r, *x; ! 263: char buf[RECSIZE]; ! 264: FILE *fp; ! 265: ! 266: fflush(stdout); /* in case someone is waiting for a prompt */ ! 267: r = gettemp(); ! 268: if (a[1] != NULL) { /* getline < file */ ! 269: x = execute(a[2]); /* filename */ ! 270: if ((int) a[1] == '|') /* input pipe */ ! 271: a[1] = (Node *) LE; /* arbitrary flag */ ! 272: fp = openfile((int) a[1], getsval(x)); ! 273: tempfree(x); ! 274: if (fp == NULL) ! 275: n = -1; ! 276: else ! 277: n = readrec(buf, sizeof(buf), fp); ! 278: if (n <= 0) { ! 279: ; ! 280: } else if (a[0] != NULL) { /* getline var <file */ ! 281: setsval(execute(a[0]), buf); ! 282: } else { /* getline <file */ ! 283: if (!(recloc->tval & DONTFREE)) ! 284: xfree(recloc->sval); ! 285: strcpy(record, buf); ! 286: recloc->sval = record; ! 287: recloc->tval = REC | STR | DONTFREE; ! 288: donerec = 1; donefld = 0; ! 289: } ! 290: } else { /* bare getline; use current input */ ! 291: if (a[0] == NULL) /* getline */ ! 292: n = getrec(record); ! 293: else { /* getline var */ ! 294: n = getrec(buf); ! 295: setsval(execute(a[0]), buf); ! 296: } ! 297: } ! 298: setfval(r, (Awkfloat) n); ! 299: return r; ! 300: } ! 301: ! 302: Cell *getnf(a,n) register Node **a; ! 303: { ! 304: if (donefld == 0) ! 305: fldbld(); ! 306: return (Cell *) a[0]; ! 307: } ! 308: ! 309: Cell *array(a,n) register Node **a; ! 310: { ! 311: register Cell *x, *y, *z; ! 312: register char *s; ! 313: ! 314: x = execute(a[0]); /* Cell* for symbol table */ ! 315: y = execute(a[1]); /* subscript */ ! 316: s = getsval(y); ! 317: if (!isarr(x)) { ! 318: xfree(x->sval); ! 319: x->tval &= ~STR; ! 320: x->tval |= ARR; ! 321: x->sval = (char *) makesymtab(); ! 322: } ! 323: z = setsymtab(s, "", 0.0, STR|NUM, x->sval); ! 324: z->ctype = OCELL; ! 325: z->csub = CVAR; ! 326: tempfree(x); ! 327: tempfree(y); ! 328: return(z); ! 329: } ! 330: ! 331: Cell *delete(a, n) Node **a; ! 332: { ! 333: Cell *x, *y; ! 334: ! 335: x = execute(a[0]); /* Cell* for symbol table */ ! 336: y = execute(a[1]); /* subscript */ ! 337: freeelem(x, getsval(y)); ! 338: tempfree(y); ! 339: tempfree(x); ! 340: return true; ! 341: } ! 342: ! 343: Cell *intest(a, n) Node **a; ! 344: { ! 345: register Cell *x, *ap; ! 346: int k; ! 347: ! 348: ap = execute(a[1]); /* array name */ ! 349: if (!isarr(ap)) ! 350: error(FATAL, "%s is not an array", ap->nval); ! 351: x = execute(a[0]); /* expr */ ! 352: getsval(x); ! 353: k = lookup(x->sval, (Cell **) ap->sval) == NULL; ! 354: tempfree(x); ! 355: tempfree(ap); ! 356: if (k) ! 357: return(false); ! 358: else ! 359: return(true); ! 360: } ! 361: ! 362: ! 363: Cell *matchop(a,n) Node **a; ! 364: { ! 365: register Cell *x, *y; ! 366: register char *s, *t; ! 367: register int i; ! 368: static struct fa *pfa = NULL; ! 369: static char *prevre = NULL; ! 370: ! 371: x = execute(a[1]); ! 372: s = getsval(x); ! 373: if (a[0] == 0) ! 374: i = match(a[2], s); ! 375: else { ! 376: y = execute(a[2]); ! 377: t = getsval(y); ! 378: if (pfa == NULL) { ! 379: pfa = makedfa(reparse(t), 0); ! 380: prevre = tostring(t); ! 381: } else if (strcmp(t, prevre) != 0) { ! 382: free(prevre); ! 383: prevre = tostring(t); ! 384: freefa(pfa); ! 385: pfa = makedfa(reparse(t), 0); ! 386: } ! 387: i = match(pfa, s); ! 388: tempfree(y); ! 389: } ! 390: tempfree(x); ! 391: if (n == MATCH && i == 1 || n == NOTMATCH && i == 0) ! 392: return(true); ! 393: else ! 394: return(false); ! 395: } ! 396: ! 397: ! 398: Cell *boolop(a,n) Node **a; ! 399: { ! 400: register Cell *x, *y; ! 401: register int i; ! 402: ! 403: x = execute(a[0]); ! 404: i = istrue(x); ! 405: tempfree(x); ! 406: switch (n) { ! 407: case BOR: ! 408: if (i) return(true); ! 409: y = execute(a[1]); ! 410: i = istrue(y); ! 411: tempfree(y); ! 412: if (i) return(true); ! 413: else return(false); ! 414: case AND: ! 415: if ( !i ) return(false); ! 416: y = execute(a[1]); ! 417: i = istrue(y); ! 418: tempfree(y); ! 419: if (i) return(true); ! 420: else return(false); ! 421: case NOT: ! 422: if (i) return(false); ! 423: else return(true); ! 424: default: ! 425: error(FATAL, "unknown boolean operator %d", n); ! 426: } ! 427: } ! 428: ! 429: Cell *relop(a,n) Node **a; ! 430: { ! 431: register int i; ! 432: register Cell *x, *y; ! 433: Awkfloat j; ! 434: ! 435: x = execute(a[0]); ! 436: y = execute(a[1]); ! 437: if (x->tval&NUM && y->tval&NUM) { ! 438: j = x->fval - y->fval; ! 439: i = j<0? -1: (j>0? 1: 0); ! 440: } else { ! 441: i = strcmp(getsval(x), getsval(y)); ! 442: } ! 443: tempfree(x); ! 444: tempfree(y); ! 445: switch (n) { ! 446: case LT: if (i<0) return(true); ! 447: else return(false); ! 448: case LE: if (i<=0) return(true); ! 449: else return(false); ! 450: case NE: if (i!=0) return(true); ! 451: else return(false); ! 452: case EQ: if (i == 0) return(true); ! 453: else return(false); ! 454: case GE: if (i>=0) return(true); ! 455: else return(false); ! 456: case GT: if (i>0) return(true); ! 457: else return(false); ! 458: default: ! 459: error(FATAL, "unknown relational operator %d", n); ! 460: } ! 461: } ! 462: ! 463: tfree(a) register Cell *a; ! 464: { ! 465: xfree(a->sval); ! 466: a->tval = 0; ! 467: a->ctype = OCELL; ! 468: a->cnext = tmps; ! 469: tmps = a; ! 470: } ! 471: ! 472: Cell *gettemp() ! 473: { int i; ! 474: register Cell *x; ! 475: ! 476: if (!tmps) { ! 477: tmps = (Cell *) Calloc(100, sizeof(Cell)); ! 478: if (!tmps) ! 479: error(FATAL, "no space for temporaries"); ! 480: for(i = 1; i < 100; i++) ! 481: tmps[i-1].cnext = &tmps[i]; ! 482: tmps[i-1].cnext = 0; ! 483: } ! 484: x = tmps; ! 485: tmps = x->cnext; ! 486: *x = tempcell; ! 487: return(x); ! 488: } ! 489: ! 490: Cell *indirect(a,n) Node **a; ! 491: { ! 492: register Cell *x; ! 493: register int m; ! 494: register char *s; ! 495: Cell *fieldadr(); ! 496: ! 497: x = execute(a[0]); ! 498: m = getfval(x); ! 499: if (m == 0 && !isnumber(s = getsval(x))) /* suspicion! */ ! 500: error(FATAL, "illegal field $(%s)", s); ! 501: tempfree(x); ! 502: x = fieldadr(m); ! 503: x->ctype = OCELL; ! 504: x->csub = CFLD; ! 505: return(x); ! 506: } ! 507: ! 508: Cell *substr(a, nnn) Node **a; ! 509: { ! 510: register int k, m, n; ! 511: register char *s, temp; ! 512: register Cell *x; ! 513: ! 514: x = execute(a[0]); ! 515: s = getsval(x); ! 516: k = strlen(s) + 1; ! 517: tempfree(x); ! 518: if (k <= 1) { ! 519: x = gettemp(); ! 520: setsval(x, ""); ! 521: return(x); ! 522: } ! 523: x = execute(a[1]); ! 524: m = getfval(x); ! 525: if (m <= 0) ! 526: m = 1; ! 527: else if (m > k) ! 528: m = k; ! 529: tempfree(x); ! 530: if (a[2] != 0) { ! 531: x = execute(a[2]); ! 532: n = getfval(x); ! 533: tempfree(x); ! 534: } ! 535: else ! 536: n = k - 1; ! 537: if (n < 0) ! 538: n = 0; ! 539: else if (n > k - m) ! 540: n = k - m; ! 541: dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s); ! 542: x = gettemp(); ! 543: temp = s[n+m-1]; /* with thanks to John Linderman */ ! 544: s[n+m-1] = '\0'; ! 545: setsval(x, s + m - 1); ! 546: s[n+m-1] = temp; ! 547: return(x); ! 548: } ! 549: ! 550: Cell *sindex(a, nnn) Node **a; ! 551: { ! 552: register Cell *x; ! 553: register char *s1, *s2, *p1, *p2, *q; ! 554: ! 555: x = execute(a[0]); ! 556: s1 = getsval(x); ! 557: tempfree(x); ! 558: x = execute(a[1]); ! 559: s2 = getsval(x); ! 560: tempfree(x); ! 561: ! 562: x = gettemp(); ! 563: for (p1 = s1; *p1 != '\0'; p1++) { ! 564: for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) ! 565: ; ! 566: if (*p2 == '\0') { ! 567: setfval(x, (Awkfloat) (p1 - s1 + 1)); /* origin 1 */ ! 568: return(x); ! 569: } ! 570: } ! 571: setfval(x, 0.0); ! 572: return(x); ! 573: } ! 574: ! 575: char *format(buf, s, a) char *buf, *s; Node *a; ! 576: { ! 577: char fmt[RECSIZE]; ! 578: register char *p, *t, *os; ! 579: register Cell *x; ! 580: int flag = 0; ! 581: Awkfloat xf; ! 582: ! 583: os = s; ! 584: p = buf; ! 585: while (*s) { ! 586: if (*s != '%') { ! 587: *p++ = *s++; ! 588: continue; ! 589: } ! 590: if (*(s+1) == '%') { ! 591: *p++ = '%'; ! 592: s += 2; ! 593: continue; ! 594: } ! 595: for (t=fmt; (*t++ = *s) != '\0'; s++) ! 596: if (islower(*s) && *s != 'l') ! 597: break; ! 598: *t = '\0'; ! 599: if (t >= fmt + sizeof(fmt)) ! 600: error(FATAL, "format item %.20s... too long", os); ! 601: switch (*s) { ! 602: case 'f': case 'e': case 'g': ! 603: flag = 1; ! 604: break; ! 605: case 'd': ! 606: flag = 2; ! 607: if(*(s-1) == 'l') break; ! 608: *(t-1) = 'l'; ! 609: *t = 'd'; ! 610: *++t = '\0'; ! 611: break; ! 612: case 'o': case 'x': case 'u': ! 613: flag = *(s-1) == 'l' ? 2 : 3; ! 614: break; ! 615: case 's': ! 616: flag = 4; ! 617: break; ! 618: case 'c': ! 619: flag = 5; ! 620: break; ! 621: default: ! 622: flag = 0; ! 623: break; ! 624: } ! 625: if (flag == 0) { ! 626: sprintf(p, "%s", fmt); ! 627: p += strlen(p); ! 628: continue; ! 629: } ! 630: if (a == NULL) ! 631: error(FATAL, "not enough args in printf(%s)", os); ! 632: x = execute(a); ! 633: a = a->nnext; ! 634: if (flag != 4) /* watch out for converting to numbers! */ ! 635: xf = getfval(x); ! 636: switch (flag) { ! 637: case 1: sprintf(p, fmt, xf); break; ! 638: case 2: sprintf(p, fmt, (long) xf); break; ! 639: case 3: sprintf(p, fmt, (int) xf); break; ! 640: case 4: sprintf(p, fmt, getsval(x)); break; ! 641: case 5: sprintf(p, fmt, (int) xf); break; ! 642: } ! 643: tempfree(x); ! 644: p += strlen(p); ! 645: s++; ! 646: } ! 647: *p = '\0'; ! 648: return buf; ! 649: } ! 650: ! 651: Cell *asprintf(a,n) Node **a; ! 652: { ! 653: register Cell *x; ! 654: register Node *y; ! 655: char buf[RECSIZE]; ! 656: ! 657: y = a[0]->nnext; ! 658: x = execute(a[0]); ! 659: format(buf, getsval(x), y); ! 660: tempfree(x); ! 661: x = gettemp(); ! 662: x->sval = tostring(buf); ! 663: x->tval = STR; ! 664: return(x); ! 665: } ! 666: ! 667: Cell *aprintf(a,n) Node **a; ! 668: { ! 669: FILE *fp; ! 670: register Cell *x; ! 671: register Node *y; ! 672: char buf[RECSIZE]; ! 673: ! 674: y = a[0]->nnext; ! 675: x = execute(a[0]); ! 676: format(buf, getsval(x), y); ! 677: tempfree(x); ! 678: if (a[1] == NULL) ! 679: fputs(buf, stdout); ! 680: else { ! 681: fp = redirect((int)a[1], a[2]); ! 682: fputs(buf, fp); ! 683: fflush(fp); ! 684: } ! 685: return(true); ! 686: } ! 687: ! 688: Cell *arith(a,n) Node **a; ! 689: { ! 690: Awkfloat i, j; ! 691: register Cell *x, *y, *z; ! 692: ! 693: x = execute(a[0]); ! 694: i = getfval(x); ! 695: tempfree(x); ! 696: if (n != UMINUS) { ! 697: y = execute(a[1]); ! 698: j = getfval(y); ! 699: tempfree(y); ! 700: } ! 701: z = gettemp(); ! 702: switch (n) { ! 703: case ADD: ! 704: i += j; ! 705: break; ! 706: case MINUS: ! 707: i -= j; ! 708: break; ! 709: case MULT: ! 710: i *= j; ! 711: break; ! 712: case DIVIDE: ! 713: if (j == 0) ! 714: error(FATAL, "division by zero"); ! 715: i /= j; ! 716: break; ! 717: case MOD: ! 718: if (j == 0) ! 719: error(FATAL, "division by zero in mod"); ! 720: i = i - j*(long)(i/j); ! 721: break; ! 722: case UMINUS: ! 723: i = -i; ! 724: break; ! 725: case POWER: ! 726: i = errcheck(pow(i, j), "pow"); ! 727: break; ! 728: default: ! 729: error(FATAL, "illegal arithmetic operator %d", n); ! 730: } ! 731: setfval(z, i); ! 732: return(z); ! 733: } ! 734: ! 735: Cell *incrdecr(a, n) Node **a; ! 736: { ! 737: register Cell *x, *z; ! 738: register int k; ! 739: Awkfloat xf; ! 740: ! 741: x = execute(a[0]); ! 742: xf = getfval(x); ! 743: k = (n == PREINCR || n == POSTINCR) ? 1 : -1; ! 744: if (n == PREINCR || n == PREDECR) { ! 745: setfval(x, xf + k); ! 746: return(x); ! 747: } ! 748: z = gettemp(); ! 749: setfval(z, xf); ! 750: setfval(x, xf + k); ! 751: tempfree(x); ! 752: return(z); ! 753: } ! 754: ! 755: Cell *assign(a,n) Node **a; ! 756: { ! 757: register Cell *x, *y; ! 758: Awkfloat xf, yf; ! 759: ! 760: x = execute(a[0]); ! 761: y = execute(a[1]); ! 762: if (n == ASSIGN) { /* ordinary assignment */ ! 763: if ((y->tval & (STR|NUM)) == (STR|NUM)) { ! 764: setsval(x, getsval(y)); ! 765: x->fval = getfval(y); ! 766: x->tval |= NUM; ! 767: } ! 768: else if (y->tval & STR) ! 769: setsval(x, getsval(y)); ! 770: else if (y->tval & NUM) ! 771: setfval(x, getfval(y)); ! 772: tempfree(y); ! 773: return(x); ! 774: } ! 775: xf = getfval(x); ! 776: yf = getfval(y); ! 777: switch (n) { ! 778: case ADDEQ: ! 779: xf += yf; ! 780: break; ! 781: case SUBEQ: ! 782: xf -= yf; ! 783: break; ! 784: case MULTEQ: ! 785: xf *= yf; ! 786: break; ! 787: case DIVEQ: ! 788: if (yf == 0) ! 789: error(FATAL, "division by zero"); ! 790: xf /= yf; ! 791: break; ! 792: case MODEQ: ! 793: if (yf == 0) ! 794: error(FATAL, "division by zero"); ! 795: xf = xf - yf*(long)(xf/yf); ! 796: break; ! 797: case POWEQ: ! 798: xf = errcheck(pow(xf, yf), "pow"); ! 799: break; ! 800: default: ! 801: error(FATAL, "illegal assignment operator %d", n); ! 802: break; ! 803: } ! 804: tempfree(y); ! 805: setfval(x, xf); ! 806: return(x); ! 807: } ! 808: ! 809: Cell *cat(a,q) Node **a; ! 810: { ! 811: register Cell *x, *y, *z; ! 812: register int n1, n2; ! 813: register char *s; ! 814: ! 815: x = execute(a[0]); ! 816: y = execute(a[1]); ! 817: getsval(x); ! 818: getsval(y); ! 819: n1 = strlen(x->sval); ! 820: n2 = strlen(y->sval); ! 821: s = (char *) Malloc(n1 + n2 + 1); ! 822: strcpy(s, x->sval); ! 823: strcpy(s+n1, y->sval); ! 824: tempfree(y); ! 825: z = gettemp(); ! 826: z->sval = s; ! 827: z->tval = STR; ! 828: tempfree(x); ! 829: return(z); ! 830: } ! 831: ! 832: Cell *pastat(a,n) Node **a; ! 833: { ! 834: register Cell *x; ! 835: ! 836: if (a[0] == 0) ! 837: x = execute(a[1]); ! 838: else { ! 839: x = execute(a[0]); ! 840: if (istrue(x)) { ! 841: tempfree(x); ! 842: x = execute(a[1]); ! 843: } ! 844: } ! 845: return x; ! 846: } ! 847: ! 848: Cell *dopa2(a,n) Node **a; ! 849: { ! 850: register Cell *x; ! 851: register int pair; ! 852: ! 853: pair = (int) a[3]; ! 854: if (pairstack[pair] == 0) { ! 855: x = execute(a[0]); ! 856: if (istrue(x)) ! 857: pairstack[pair] = 1; ! 858: tempfree(x); ! 859: } ! 860: if (pairstack[pair] == 1) { ! 861: x = execute(a[1]); ! 862: if (istrue(x)) ! 863: pairstack[pair] = 0; ! 864: tempfree(x); ! 865: x = execute(a[2]); ! 866: return(x); ! 867: } ! 868: return(false); ! 869: } ! 870: ! 871: Cell *split(a,nnn) Node **a; ! 872: { ! 873: Cell *x, *y, *ap; ! 874: register char *s; ! 875: register int sep; ! 876: char *t, temp, num[5], *fs; ! 877: int n, tempstat; ! 878: ! 879: y = execute(a[0]); ! 880: s = getsval(y); ! 881: if (a[2] == 0) ! 882: fs = *FS; ! 883: else { ! 884: x = execute(a[2]); ! 885: fs = getsval(x); ! 886: } ! 887: sep = *fs; ! 888: ap = execute(a[1]); /* array name */ ! 889: freesymtab(ap); ! 890: dprintf("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs); ! 891: ap->tval &= ~STR; ! 892: ap->tval |= ARR; ! 893: ap->sval = (char *) makesymtab(); ! 894: ! 895: n = 0; ! 896: if (*s != '\0' && strlen(fs) > 1) { /* reg expr */ ! 897: extern char *patbeg; ! 898: extern int patlen; ! 899: static fa *pfa = NULL; ! 900: static char *prevfs = NULL; ! 901: if (pfa == NULL) { /* first time thru */ ! 902: pfa = makedfa(reparse(fs), 1); ! 903: prevfs = tostring(fs); ! 904: } else if (strcmp(fs, prevfs) != 0) { /* new fa needed for new FS */ ! 905: freefa(pfa); ! 906: Free(prevfs); ! 907: pfa = makedfa(reparse(fs), 1); ! 908: prevfs = tostring(fs); ! 909: } ! 910: if (nematch(pfa,s)) { ! 911: tempstat = pfa->initstat; ! 912: pfa->initstat = 2; ! 913: do { ! 914: n++; ! 915: sprintf(num, "%d", n); ! 916: temp = *patbeg; ! 917: *patbeg = '\0'; ! 918: if (isnumber(s)) ! 919: setsymtab(num, s, atof(s), STR|NUM, ap->sval); ! 920: else ! 921: setsymtab(num, s, 0.0, STR, ap->sval); ! 922: *patbeg = temp; ! 923: s = patbeg + patlen; ! 924: if ((*(patbeg+patlen-1) == 0) || (*s == 0)) { ! 925: n++; ! 926: sprintf(num, "%d", n); ! 927: setsymtab(num, "", 0.0, STR, ap->sval); ! 928: pfa->initstat = tempstat; ! 929: goto spdone; ! 930: } ! 931: } while(nematch(pfa,s)); ! 932: } ! 933: n++; ! 934: sprintf(num, "%d", n); ! 935: if (isnumber(s)) ! 936: setsymtab(num, s, atof(s), STR|NUM, ap->sval); ! 937: else ! 938: setsymtab(num, s, 0.0, STR, ap->sval); ! 939: } else if (sep == ' ') { ! 940: for (n = 0; ; ) { ! 941: while (*s == ' ' || *s == '\t' || *s == '\n') ! 942: s++; ! 943: if (*s == 0) ! 944: break; ! 945: n++; ! 946: t = s; ! 947: do ! 948: s++; ! 949: while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); ! 950: temp = *s; ! 951: *s = '\0'; ! 952: sprintf(num, "%d", n); ! 953: if (isnumber(t)) ! 954: setsymtab(num, t, atof(t), STR|NUM, ap->sval); ! 955: else ! 956: setsymtab(num, t, 0.0, STR, ap->sval); ! 957: *s = temp; ! 958: if (*s != 0) ! 959: s++; ! 960: } ! 961: } else if (*s != 0) { ! 962: for (;;) { ! 963: n++; ! 964: t = s; ! 965: while (*s != sep && *s != '\n' && *s != '\0') ! 966: s++; ! 967: temp = *s; ! 968: *s = '\0'; ! 969: sprintf(num, "%d", n); ! 970: if (isnumber(t)) ! 971: setsymtab(num, t, atof(t), STR|NUM, ap->sval); ! 972: else ! 973: setsymtab(num, t, 0.0, STR, ap->sval); ! 974: *s = temp; ! 975: if (*s++ == 0) ! 976: break; ! 977: } ! 978: } ! 979: spdone: ! 980: tempfree(ap); ! 981: tempfree(y); ! 982: if (a[2] != 0) ! 983: tempfree(x); ! 984: x = gettemp(); ! 985: x->tval = NUM; ! 986: x->fval = n; ! 987: return(x); ! 988: } ! 989: ! 990: Cell *ifstat(a,n) Node **a; ! 991: { ! 992: register Cell *x; ! 993: ! 994: x = execute(a[0]); ! 995: if (istrue(x)) { ! 996: tempfree(x); ! 997: x = execute(a[1]); ! 998: } ! 999: else if (a[2] != 0) { ! 1000: tempfree(x); ! 1001: x = execute(a[2]); ! 1002: } ! 1003: return(x); ! 1004: } ! 1005: ! 1006: Cell *whilestat(a,n) Node **a; ! 1007: { ! 1008: register Cell *x; ! 1009: ! 1010: for (;;) { ! 1011: x = execute(a[0]); ! 1012: if (!istrue(x)) return(x); ! 1013: tempfree(x); ! 1014: x = execute(a[1]); ! 1015: if (isbreak(x)) { ! 1016: x = true; ! 1017: return(x); ! 1018: } ! 1019: if (isnext(x) || isexit(x) || isret(x)) ! 1020: return(x); ! 1021: tempfree(x); ! 1022: } ! 1023: } ! 1024: ! 1025: Cell *forstat(a,n) Node **a; ! 1026: { ! 1027: register Cell *x; ! 1028: ! 1029: x = execute(a[0]); ! 1030: tempfree(x); ! 1031: for (;;) { ! 1032: if (a[1]!=0) { ! 1033: x = execute(a[1]); ! 1034: if (!istrue(x)) return(x); ! 1035: else tempfree(x); ! 1036: } ! 1037: x = execute(a[3]); ! 1038: if (isbreak(x)) { /* turn off break */ ! 1039: x = true; ! 1040: return(x); ! 1041: } ! 1042: if (isnext(x) || isexit(x) || isret(x)) ! 1043: return(x); ! 1044: tempfree(x); ! 1045: x = execute(a[2]); ! 1046: tempfree(x); ! 1047: } ! 1048: } ! 1049: ! 1050: int indepth = 0; /* depth of for (i in ...) statements */ ! 1051: ! 1052: Cell *instat(a, n) Node **a; ! 1053: { ! 1054: register Cell *x, *vp, *arrayp, *cp, *ncp, **tp; ! 1055: int i; ! 1056: ! 1057: vp = execute(a[0]); ! 1058: arrayp = execute(a[1]); ! 1059: if (!isarr(arrayp)) ! 1060: error(FATAL, "%s is not an array", arrayp->nval); ! 1061: tp = (Cell **) arrayp->sval; ! 1062: tempfree(arrayp); ! 1063: indepth++; ! 1064: for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */ ! 1065: for (cp = tp[i]; cp != NULL; cp = ncp) { ! 1066: setsval(vp, cp->nval); ! 1067: ncp = cp->cnext; ! 1068: x = execute(a[2]); ! 1069: if (isbreak(x)) { ! 1070: tempfree(vp); ! 1071: x = true; ! 1072: indepth--; ! 1073: return(x); ! 1074: } ! 1075: if (isnext(x) || isexit(x) || isret(x)) { ! 1076: tempfree(vp); ! 1077: indepth--; ! 1078: return(x); ! 1079: } ! 1080: tempfree(x); ! 1081: } ! 1082: } ! 1083: indepth--; ! 1084: } ! 1085: ! 1086: Cell *bltin(a,n) Node **a; ! 1087: { ! 1088: register Cell *x, *y; ! 1089: Awkfloat u; ! 1090: register int t; ! 1091: ! 1092: t = (int) a[0]; ! 1093: x = execute(a[1]); ! 1094: switch (t) { ! 1095: case FLENGTH: ! 1096: u = (Awkfloat) strlen(getsval(x)); break; ! 1097: case FLOG: ! 1098: u = errcheck(log(getfval(x)), "log"); break; ! 1099: case FINT: ! 1100: u = (Awkfloat) (long) getfval(x); break; ! 1101: case FEXP: ! 1102: u = errcheck(exp(getfval(x)), "exp"); break; ! 1103: case FSQRT: ! 1104: u = errcheck(sqrt(getfval(x)), "sqrt"); break; ! 1105: case FSIN: ! 1106: u = sin(getfval(x)); break; ! 1107: case FCOS: ! 1108: u = cos(getfval(x)); break; ! 1109: case FATAN: ! 1110: y = execute(a[1]->nnext); ! 1111: u = atan2(getfval(x), getfval(y)); ! 1112: tempfree(y); ! 1113: break; ! 1114: case FSYSTEM: ! 1115: fflush(stdout); /* in case something buffered already */ ! 1116: u = (Awkfloat) system(getsval(x)) / 256; ! 1117: break; ! 1118: case FRAND: ! 1119: u = (Awkfloat) rand() / 32767.0; break; /* 2^31-1 better on some systems? */ ! 1120: case FSRAND: ! 1121: if (x->tval & REC) ! 1122: u = (Awkfloat) srand(time(0)); ! 1123: else ! 1124: u = (Awkfloat) srand((int)getfval(x)); ! 1125: break; ! 1126: default: ! 1127: error(FATAL, "illegal function type %d", t); break; ! 1128: } ! 1129: tempfree(x); ! 1130: x = gettemp(); ! 1131: setfval(x, u); ! 1132: return(x); ! 1133: } ! 1134: ! 1135: Cell *print(a,n) Node **a; ! 1136: { ! 1137: register Node *x; ! 1138: register Cell *y; ! 1139: FILE *fp; ! 1140: ! 1141: if (a[1] == 0) ! 1142: fp = stdout; ! 1143: else ! 1144: fp = redirect((int)a[1], a[2]); ! 1145: for (x=a[0]; x!=NULL; x=x->nnext) { ! 1146: y = execute(x); ! 1147: fputs(getsval(y), fp); ! 1148: tempfree(y); ! 1149: if (x->nnext == NULL) ! 1150: fputs(*ORS, fp); ! 1151: else ! 1152: fputs(*OFS, fp); ! 1153: } ! 1154: if (a[1] != 0) ! 1155: fflush(fp); ! 1156: return(true); ! 1157: } ! 1158: ! 1159: Cell *nullproc() {} ! 1160: ! 1161: ! 1162: #define FILENUM 15 ! 1163: struct ! 1164: { ! 1165: FILE *fp; ! 1166: char *fname; ! 1167: int mode; /* '|', 'a', 'w' */ ! 1168: int imode; /* GT, LE, ... */ ! 1169: } files[FILENUM]; ! 1170: FILE *popen(); ! 1171: ! 1172: FILE *redirect(a, b) ! 1173: Node *b; ! 1174: { ! 1175: FILE *fp; ! 1176: Cell *x; ! 1177: char *fname; ! 1178: ! 1179: x = execute(b); ! 1180: fname = getsval(x); ! 1181: fp = openfile(a, fname); ! 1182: if (fp == NULL) ! 1183: error(FATAL, "can't open file %s", fname); ! 1184: tempfree(x); ! 1185: return fp; ! 1186: } ! 1187: ! 1188: FILE *openfile(a, s) ! 1189: char *s; ! 1190: { ! 1191: register int i; ! 1192: ! 1193: if (*s == '\0') ! 1194: error(FATAL, "null file name in print or getline"); ! 1195: for (i=0; i < FILENUM; i++) ! 1196: if (strcmp(s, files[i].fname) == 0 && files[i].imode == a) ! 1197: return files[i].fp; ! 1198: for (i=0; i < FILENUM; i++) ! 1199: if (files[i].fp == 0) ! 1200: break; ! 1201: if (i >= FILENUM) ! 1202: error(FATAL, "%s makes too many open files", s); ! 1203: if (a == GT) { ! 1204: files[i].fp = fopen(s, "w"); ! 1205: files[i].mode = 'w'; ! 1206: } else if (a == APPEND) { ! 1207: files[i].fp = fopen(s, "a"); ! 1208: files[i].mode = 'a'; ! 1209: } else if (a == '|') { /* output pipe */ ! 1210: files[i].fp = popen(s, "w"); ! 1211: files[i].mode = '|'; ! 1212: } else if (a == LE) { /* input pipe */ ! 1213: files[i].fp = popen(s, "r"); ! 1214: files[i].mode = LE; ! 1215: } else if (a == LT) { /* getline <file */ ! 1216: files[i].fp = fopen(s, "r"); ! 1217: files[i].mode = 'r'; ! 1218: } else ! 1219: error(FATAL, "illegal redirection"); ! 1220: if (files[i].fp != NULL) ! 1221: files[i].fname = tostring(s); ! 1222: files[i].imode = a; ! 1223: return files[i].fp; ! 1224: } ! 1225: ! 1226: ! 1227: Cell *closefile(a) Node **a; ! 1228: { ! 1229: register Cell *x; ! 1230: int i; ! 1231: ! 1232: x = execute(a[0]); ! 1233: getsval(x); ! 1234: for (i = 0; i < FILENUM; i++) ! 1235: if (strcmp(x->sval, files[i].fname) == 0) { ! 1236: if (files[i].mode == '|' || files[i].mode == LE) ! 1237: pclose(files[i].fp); ! 1238: else ! 1239: fclose(files[i].fp); ! 1240: xfree(files[i].fname); ! 1241: files[i].fname = NULL; /* watch out for ref thru this */ ! 1242: files[i].fp = NULL; ! 1243: } ! 1244: return(x); ! 1245: } ! 1246: ! 1247: closeall() ! 1248: { ! 1249: int i; ! 1250: ! 1251: for (i = 0; i < FILENUM; i++) ! 1252: if (files[i].fp) { ! 1253: if (files[i].mode == '|' || files[i].mode == LE) ! 1254: pclose(files[i].fp); ! 1255: else ! 1256: fclose(files[i].fp); ! 1257: } ! 1258: } ! 1259: ! 1260: Cell *sub(a, nnn) Node **a; ! 1261: { ! 1262: register char *sptr, *pb, *q; ! 1263: register Cell *x, *y; ! 1264: char buf[RECSIZE], *t; ! 1265: fa *pfa; ! 1266: ! 1267: extern char *patbeg; ! 1268: extern int patlen; ! 1269: x = execute(a[3]); /* source string */ ! 1270: t = getsval(x); ! 1271: if (a[0] == 0) ! 1272: pfa = (fa *) a[1]; /* regular expression */ ! 1273: else { ! 1274: y = execute(a[1]); ! 1275: pfa = makedfa(reparse(getsval(y)), 1); ! 1276: tempfree(y); ! 1277: } ! 1278: if (pmatch(pfa, t)) { ! 1279: pb = buf; ! 1280: sptr = t; ! 1281: while (sptr < patbeg) ! 1282: *pb++ = *sptr++; ! 1283: y = execute(a[2]); /* replacement */ ! 1284: sptr = getsval(y); ! 1285: while (*sptr != 0) ! 1286: if (*sptr == '\\' && *(sptr+1) == '&') { ! 1287: sptr++; /* skip \, */ ! 1288: *pb++ = *sptr++; /* add & */ ! 1289: } else if (*sptr == '&') { ! 1290: sptr++; ! 1291: for (q = patbeg; q < patbeg+patlen; ) ! 1292: *pb++ = *q++; ! 1293: } else ! 1294: *pb++ = *sptr++; ! 1295: tempfree(y); ! 1296: sptr = patbeg + patlen; ! 1297: while (*pb++ = *sptr++) ! 1298: ; ! 1299: setsval(x, buf); ! 1300: tempfree(x); ! 1301: return (true); ! 1302: } ! 1303: tempfree(x); ! 1304: return (false); ! 1305: } ! 1306: ! 1307: Cell *gsub(a, nnn) Node **a; ! 1308: { ! 1309: register Cell *x, *y; ! 1310: register char *rptr, *sptr, *t, *pb; ! 1311: char buf[RECSIZE]; ! 1312: register fa *pfa; ! 1313: int mflag, tempstat, num; ! 1314: ! 1315: extern char *patbeg; ! 1316: extern int patlen; ! 1317: ! 1318: mflag = 0; ! 1319: num = 0; ! 1320: x = execute(a[3]); ! 1321: t = getsval(x); ! 1322: if (a[0] == 0) ! 1323: pfa = (fa *) a[1]; ! 1324: else { ! 1325: y = execute(a[1]); ! 1326: pfa = makedfa(reparse(getsval(y)), 1); ! 1327: tempfree(y); ! 1328: } ! 1329: if (pmatch(pfa, t)) { ! 1330: tempstat = pfa->initstat; ! 1331: pfa->initstat = 2; ! 1332: pb = buf; ! 1333: y = execute(a[2]); ! 1334: rptr = getsval(y); ! 1335: do { ! 1336: /* ! 1337: char *p; ! 1338: int i; ! 1339: printf("target string: %s, *patbeg = %c, patlen = %d\n", t, *patbeg, patlen); ! 1340: printf(" match found: "); ! 1341: p=patbeg; ! 1342: for (i=0; i<patlen; i++) ! 1343: printf("%c", *p++); ! 1344: printf("\n"); ! 1345: */ ! 1346: num++; ! 1347: if (patlen == 0) { /* matched empty string */ ! 1348: if (mflag == 0) { /* can replace empty */ ! 1349: sptr = rptr; ! 1350: while (*sptr != 0) ! 1351: if (*sptr == '\\' && *(sptr+1) == '&') { ! 1352: sptr++; ! 1353: *pb++ = *sptr++; ! 1354: } else if (*sptr == '&') { ! 1355: char *q; ! 1356: sptr++; ! 1357: for (q = patbeg; q < patbeg+patlen; ) ! 1358: *pb++ = *q++; ! 1359: } else ! 1360: *pb++ = *sptr++; ! 1361: } ! 1362: *pb++ = *t; ! 1363: if (*t == 0) /* at end */ ! 1364: goto done; ! 1365: t++; ! 1366: mflag = 0; ! 1367: } ! 1368: else { /* matched nonempty string */ ! 1369: if (*t == 0) { /* matched $ */ ! 1370: if (mflag == 0) { /* can replace empty */ ! 1371: sptr = rptr; ! 1372: while (*sptr != 0) ! 1373: if (*sptr == '\\' && *(sptr+1) == '&') { ! 1374: sptr++; ! 1375: *pb++ = *sptr++; ! 1376: } else if (*sptr == '&') { ! 1377: char *q; ! 1378: sptr++; ! 1379: for (q = patbeg; q < patbeg+patlen; ) ! 1380: *pb++ = *q++; ! 1381: } else ! 1382: *pb++ = *sptr++; ! 1383: } ! 1384: *pb++ = 0; ! 1385: goto done; ! 1386: } ! 1387: sptr = t; ! 1388: while (sptr < patbeg) ! 1389: *pb++ = *sptr++; ! 1390: sptr = rptr; ! 1391: while (*sptr != 0) ! 1392: if (*sptr == '\\' && *(sptr+1) == '&') { ! 1393: sptr++; ! 1394: *pb++ = *sptr++; ! 1395: } else if (*sptr == '&') { ! 1396: char *q; ! 1397: sptr++; ! 1398: for (q = patbeg; q < patbeg+patlen; ) ! 1399: *pb++ = *q++; ! 1400: } else ! 1401: *pb++ = *sptr++; ! 1402: mflag = 1; ! 1403: t = patbeg + patlen; ! 1404: if (*t == 0) { ! 1405: *pb = 0; ! 1406: goto done; ! 1407: } ! 1408: } ! 1409: } while (pmatch(pfa,t)); ! 1410: sptr = t; ! 1411: while (*pb++ = *sptr++) ! 1412: ; ! 1413: done: tempfree(y); ! 1414: setsval(x, buf); ! 1415: pfa->initstat = tempstat; ! 1416: } ! 1417: tempfree(x); ! 1418: x = gettemp(); ! 1419: x->tval = NUM; ! 1420: x->fval = num; ! 1421: return(x); ! 1422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.