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