|
|
1.1 ! root 1: #define DEBUG ! 2: #include <stdio.h> ! 3: #include <ctype.h> ! 4: #include <errno.h> ! 5: #include "awk.h" ! 6: #include "y.tab.h" ! 7: ! 8: #define getfval(p) (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : r_getfval(p)) ! 9: #define getsval(p) (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : r_getsval(p)) ! 10: ! 11: extern Awkfloat r_getfval(); ! 12: extern uchar *r_getsval(); ! 13: ! 14: FILE *infile = NULL; ! 15: uchar *file = (uchar*) ""; ! 16: uchar recdata[RECSIZE]; ! 17: uchar *record = recdata; ! 18: uchar fields[RECSIZE]; ! 19: ! 20: #define MAXFLD 100 ! 21: int donefld; /* 1 = implies rec broken into fields */ ! 22: int donerec; /* 1 = record is valid (no flds have changed) */ ! 23: ! 24: #define FINIT { OCELL, CFLD, NULL, (uchar*) "", 0.0, FLD|STR|DONTFREE } ! 25: ! 26: Cell fldtab[MAXFLD] = { /* room for fields */ ! 27: { OCELL, CFLD, (uchar*) "$0", recdata, 0.0, REC|STR|DONTFREE}, ! 28: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 29: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 30: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 31: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 32: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 33: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 34: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 35: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 36: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 37: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, ! 38: }; ! 39: int maxfld = 0; /* last used field */ ! 40: int argno = 1; /* current input argument number */ ! 41: ! 42: initgetrec() ! 43: { ! 44: infile = stdin; ! 45: *FILENAME = file = (uchar*) "-"; ! 46: } ! 47: ! 48: getrec(buf) ! 49: uchar *buf; ! 50: { ! 51: uchar *getargv(); ! 52: int c; ! 53: extern Awkfloat *ARGC; ! 54: ! 55: dprintf("RS=<%s>, FS=<%s>\n", *RS, *FS); ! 56: donefld = 0; ! 57: donerec = 1; ! 58: buf[0] = 0; ! 59: while (argno < *ARGC || infile == stdin) { ! 60: dprintf("argno=%d, file=|%s|\n", argno, file); ! 61: if (infile == NULL) { /* have to open a new file */ ! 62: file = getargv(argno); ! 63: if (*file == '\0') { /* it's been zapped */ ! 64: argno++; ! 65: continue; ! 66: } ! 67: if (isclvar(file)) { /* a var=value arg */ ! 68: setclvar(file); ! 69: argno++; ! 70: continue; ! 71: } ! 72: *FILENAME = file; ! 73: dprintf("opening file %s\n", file); ! 74: if (*file == '-' && *(file+1) == '\0') ! 75: infile = stdin; ! 76: else if ((infile = fopen(file, "r")) == NULL) ! 77: error(FATAL, "can't open %s", file); ! 78: setfval(fnrloc, 0.0); ! 79: } ! 80: c = readrec(buf, RECSIZE, infile); ! 81: if (c != 0 || buf[0] != '\0') { /* normal record */ ! 82: if (buf == record) { ! 83: if (!(recloc->tval & DONTFREE)) ! 84: xfree(recloc->sval); ! 85: recloc->sval = record; ! 86: recloc->tval = REC | STR | DONTFREE; ! 87: if (isnumber(recloc->sval)) { ! 88: recloc->fval = atof(recloc->sval); ! 89: recloc->tval |= NUM; ! 90: } ! 91: } ! 92: setfval(nrloc, nrloc->fval+1); ! 93: setfval(fnrloc, fnrloc->fval+1); ! 94: return 1; ! 95: } ! 96: /* EOF arrived on this file; set up next */ ! 97: if (infile != stdin) ! 98: fclose(infile); ! 99: infile = NULL; ! 100: argno++; ! 101: } ! 102: return 0; /* true end of file */ ! 103: } ! 104: ! 105: readrec(buf, bufsize, inf) /* read one record into buf */ ! 106: uchar *buf; ! 107: int bufsize; ! 108: FILE *inf; ! 109: { ! 110: register int sep, c; ! 111: register uchar *rr; ! 112: ! 113: if ((sep = **RS) == 0) { ! 114: sep = '\n'; ! 115: while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */ ! 116: ; ! 117: if (c != EOF) ! 118: ungetc(c, inf); ! 119: } ! 120: for (rr = buf; ; ) { ! 121: for (; (c=getc(inf)) != sep && c != EOF; *rr++ = c) ! 122: ; ! 123: if (**RS == sep || c == EOF) ! 124: break; ! 125: if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */ ! 126: break; ! 127: *rr++ = '\n'; ! 128: *rr++ = c; ! 129: } ! 130: if (rr > buf + bufsize) ! 131: error(FATAL, "input record `%.20s...' too long", buf); ! 132: *rr = 0; ! 133: dprintf("readrec saw <%s>, returns %d\n", buf, c == EOF && rr == buf ? 0 : 1); ! 134: return c == EOF && rr == buf ? 0 : 1; ! 135: } ! 136: ! 137: uchar *getargv(n) /* get ARGV[n] */ ! 138: int n; ! 139: { ! 140: Cell *x; ! 141: uchar *s, temp[10]; ! 142: extern Array *ARGVtab; ! 143: ! 144: sprintf(temp, "%d", n); ! 145: x = setsymtab(temp, "", 0.0, STR, ARGVtab); ! 146: s = getsval(x); ! 147: dprintf("getargv(%d) returns |%s|\n", n, s, NULL); ! 148: return s; ! 149: } ! 150: ! 151: setclvar(s) /* set var=value from s */ ! 152: uchar *s; ! 153: { ! 154: uchar *p; ! 155: Cell *q; ! 156: ! 157: for (p=s; *p != '='; p++) ! 158: ; ! 159: *p++ = 0; ! 160: p = qstring(p, '\0'); ! 161: q = setsymtab(s, p, 0.0, STR, symtab); ! 162: setsval(q, p); ! 163: if (isnumber(q->sval)) { ! 164: q->fval = atof(q->sval); ! 165: q->tval |= NUM; ! 166: } ! 167: dprintf("command line set %s to |%s|\n", s, p, NULL); ! 168: } ! 169: ! 170: ! 171: fldbld() ! 172: { ! 173: register uchar *r, *fr, sep; ! 174: Cell *p; ! 175: int i; ! 176: ! 177: if (donefld) ! 178: return; ! 179: if (!(recloc->tval & STR)) ! 180: getsval(recloc); ! 181: r = recloc->sval; /* was record! */ ! 182: fr = fields; ! 183: i = 0; /* number of fields accumulated here */ ! 184: if (strlen(*FS) > 1) { /* it's a regular expression */ ! 185: i = refldbld(r, *FS); ! 186: } else if ((sep = **FS) == ' ') { ! 187: for (i = 0; ; ) { ! 188: while (*r == ' ' || *r == '\t' || *r == '\n') ! 189: r++; ! 190: if (*r == 0) ! 191: break; ! 192: i++; ! 193: if (i >= MAXFLD) ! 194: break; ! 195: if (!(fldtab[i].tval & DONTFREE)) ! 196: xfree(fldtab[i].sval); ! 197: fldtab[i].sval = fr; ! 198: fldtab[i].tval = FLD | STR | DONTFREE; ! 199: do ! 200: *fr++ = *r++; ! 201: while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0'); ! 202: *fr++ = 0; ! 203: } ! 204: *fr = 0; ! 205: } else if (*r != 0) { /* if 0, it's a null field */ ! 206: for (;;) { ! 207: i++; ! 208: if (i >= MAXFLD) ! 209: break; ! 210: if (!(fldtab[i].tval & DONTFREE)) ! 211: xfree(fldtab[i].sval); ! 212: fldtab[i].sval = fr; ! 213: fldtab[i].tval = FLD | STR | DONTFREE; ! 214: while (*r != sep && *r != '\n' && *r != '\0') /* \n always a separator */ ! 215: *fr++ = *r++; ! 216: *fr++ = 0; ! 217: if (*r++ == 0) ! 218: break; ! 219: } ! 220: *fr = 0; ! 221: } ! 222: if (i >= MAXFLD) ! 223: error(FATAL, "record `%.20s...' has too many fields", record); ! 224: /* clean out junk from previous record */ ! 225: cleanfld(i, maxfld); ! 226: maxfld = i; ! 227: donefld = 1; ! 228: for (p = fldtab+1; p <= fldtab+maxfld; p++) { ! 229: if(isnumber(p->sval)) { ! 230: p->fval = atof(p->sval); ! 231: p->tval |= NUM; ! 232: } ! 233: } ! 234: setfval(nfloc, (Awkfloat) maxfld); ! 235: if (dbg) ! 236: for (p = fldtab; p <= fldtab+maxfld; p++) ! 237: printf("field %d: |%s|\n", p-fldtab, p->sval); ! 238: } ! 239: ! 240: cleanfld(n1, n2) /* clean out fields n1..n2 inclusive */ ! 241: { ! 242: static uchar *nullstat = (uchar *) ""; ! 243: register Cell *p, *q; ! 244: ! 245: for (p = &fldtab[n2], q = &fldtab[n1]; p > q; p--) { ! 246: if (!(p->tval & DONTFREE)) ! 247: xfree(p->sval); ! 248: p->tval = FLD | STR | DONTFREE; ! 249: p->sval = nullstat; ! 250: } ! 251: } ! 252: ! 253: newfld(n) /* add field n (after end) */ ! 254: { ! 255: if (n >= MAXFLD) ! 256: error(FATAL, "creating too many fields", record); ! 257: cleanfld(maxfld, n); ! 258: maxfld = n; ! 259: setfval(nfloc, (Awkfloat) n); ! 260: } ! 261: ! 262: refldbld(rec, fs) /* build fields from reg expr in FS */ ! 263: uchar *rec, *fs; ! 264: { ! 265: fa *makedfa(); ! 266: uchar *fr; ! 267: int i, tempstat; ! 268: fa *pfa; ! 269: ! 270: fr = fields; ! 271: *fr = '\0'; ! 272: if (*rec == '\0') ! 273: return 0; ! 274: pfa = makedfa(fs, 1); ! 275: dprintf("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs); ! 276: tempstat = pfa->initstat; ! 277: for (i = 1; i < MAXFLD; i++) { ! 278: if (!(fldtab[i].tval & DONTFREE)) ! 279: xfree(fldtab[i].sval); ! 280: fldtab[i].tval = FLD | STR | DONTFREE; ! 281: fldtab[i].sval = fr; ! 282: dprintf("refldbld: i=%d\n", i); ! 283: if (nematch(pfa, rec)) { ! 284: pfa->initstat = 2; ! 285: dprintf("match %s (%d chars)\n", patbeg, patlen); ! 286: strncpy(fr, rec, patbeg-rec); ! 287: fr += patbeg - rec + 1; ! 288: *(fr-1) = '\0'; ! 289: rec = patbeg + patlen; ! 290: } else { ! 291: dprintf("no match %s\n", rec); ! 292: strcpy(fr, rec); ! 293: pfa->initstat = tempstat; ! 294: break; ! 295: } ! 296: } ! 297: return i; ! 298: } ! 299: ! 300: recbld() ! 301: { ! 302: int i; ! 303: register uchar *r, *p; ! 304: static uchar rec[RECSIZE]; ! 305: ! 306: if (donerec == 1) ! 307: return; ! 308: r = rec; ! 309: for (i = 1; i <= *NF; i++) { ! 310: p = getsval(&fldtab[i]); ! 311: while (*r = *p++) ! 312: r++; ! 313: if (i < *NF) ! 314: for (p = *OFS; *r = *p++; ) ! 315: r++; ! 316: } ! 317: *r = '\0'; ! 318: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL); ! 319: recloc->tval = REC | STR | DONTFREE; ! 320: recloc->sval = record = rec; ! 321: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL); ! 322: if (r > record + RECSIZE) ! 323: error(FATAL, "built giant record `%.20s...'", record); ! 324: dprintf("recbld = |%s|\n", record, NULL, NULL); ! 325: donerec = 1; ! 326: } ! 327: ! 328: Cell *fieldadr(n) ! 329: { ! 330: if (n < 0 || n >= MAXFLD) ! 331: error(FATAL, "trying to access field %d", n); ! 332: return(&fldtab[n]); ! 333: } ! 334: ! 335: int errorflag = 0; ! 336: ! 337: yyerror(s, a1, a2, a3, a4, a5, a6, a7) ! 338: uchar *s; ! 339: { ! 340: extern uchar *cmdname, *curfname; ! 341: static int been_here = 0; ! 342: ! 343: if (been_here++ > 2) ! 344: return; ! 345: fprintf(stderr, "%s: ", cmdname); ! 346: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); ! 347: fprintf(stderr, " at source line %d", lineno); ! 348: if (curfname != NULL) ! 349: fprintf(stderr, " in function %s", curfname); ! 350: fprintf(stderr, "\n"); ! 351: errorflag = 2; ! 352: eprint(); ! 353: } ! 354: ! 355: fpecatch() ! 356: { ! 357: error(FATAL, "floating point exception"); ! 358: } ! 359: ! 360: bracecheck() ! 361: { ! 362: extern int bracecnt, brackcnt, parencnt; ! 363: int c; ! 364: static int beenhere = 0; ! 365: ! 366: if (beenhere++) ! 367: return; ! 368: while ((c = input()) != EOF && c != '\0') ! 369: bclass(c); ! 370: bcheck2(bracecnt, '{', '}'); ! 371: bcheck2(brackcnt, '[', ']'); ! 372: bcheck2(parencnt, '(', ')'); ! 373: } ! 374: ! 375: bcheck2(n, c1, c2) ! 376: { ! 377: if (n == 1) ! 378: fprintf(stderr, "\tmissing %c\n", c2); ! 379: else if (n > 1) ! 380: fprintf(stderr, "\t%d missing %c's\n", n, c2); ! 381: else if (n == -1) ! 382: fprintf(stderr, "\textra %c\n", c2); ! 383: else if (n < -1) ! 384: fprintf(stderr, "\t%d extra %c's\n", -n, c2); ! 385: } ! 386: ! 387: error(f, s, a1, a2, a3, a4, a5, a6, a7) ! 388: char *s; ! 389: { ! 390: extern Node *curnode; ! 391: extern uchar *cmdname; ! 392: ! 393: fprintf(stderr, "%s: ", cmdname); ! 394: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); ! 395: fprintf(stderr, "\n"); ! 396: if (NR && *NR > 0) { ! 397: fprintf(stderr, " input record number %g", *FNR); ! 398: if (strcmp(*FILENAME, "-") != 0) ! 399: fprintf(stderr, ", file %s", *FILENAME); ! 400: fprintf(stderr, "\n"); ! 401: } ! 402: if (curnode) ! 403: fprintf(stderr, " source line number %d\n", curnode->lineno); ! 404: else if (lineno) ! 405: fprintf(stderr, " source line number %d\n", lineno); ! 406: eprint(); ! 407: if (f) { ! 408: if (dbg) ! 409: abort(); ! 410: exit(2); ! 411: } ! 412: } ! 413: ! 414: eprint() /* try to print context around error */ ! 415: { ! 416: uchar *p, *q; ! 417: int c; ! 418: static int been_here = 0; ! 419: extern uchar ebuf[300], *ep; ! 420: ! 421: if (compile_time == 0 || been_here++ > 0) ! 422: return; ! 423: p = ep - 1; ! 424: if (p > ebuf && *p == '\n') ! 425: p--; ! 426: for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--) ! 427: ; ! 428: while (*p == '\n') ! 429: p++; ! 430: fprintf(stderr, " context is\n\t"); ! 431: for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) ! 432: ; ! 433: while (p < q) ! 434: putc(*p++, stderr); ! 435: fprintf(stderr, " >>> "); ! 436: while (p < ep) ! 437: putc(*p++, stderr); ! 438: fprintf(stderr, " <<< "); ! 439: if (*ep) ! 440: while ((c = input()) != '\n' && c != '\0' && c != EOF) { ! 441: putc(c, stderr); ! 442: bclass(c); ! 443: } ! 444: putc('\n', stderr); ! 445: ep = ebuf; ! 446: } ! 447: ! 448: bclass(c) ! 449: { ! 450: switch (c) { ! 451: case '{': bracecnt++; break; ! 452: case '}': bracecnt--; break; ! 453: case '[': brackcnt++; break; ! 454: case ']': brackcnt--; break; ! 455: case '(': parencnt++; break; ! 456: case ')': parencnt--; break; ! 457: } ! 458: } ! 459: ! 460: double errcheck(x, s) ! 461: double x; ! 462: uchar *s; ! 463: { ! 464: extern int errno; ! 465: ! 466: if (errno == EDOM) { ! 467: errno = 0; ! 468: error(!FATAL, "%s argument out of domain", s); ! 469: x = 1; ! 470: } else if (errno == ERANGE) { ! 471: errno = 0; ! 472: error(!FATAL, "%s result out of range", s); ! 473: x = 1; ! 474: } ! 475: return x; ! 476: } ! 477: ! 478: PUTS(s) uchar *s; { ! 479: dprintf("%s\n", s, NULL, NULL); ! 480: } ! 481: ! 482: isclvar(s) /* is s of form var=something? */ ! 483: char *s; ! 484: { ! 485: for ( ; *s; s++) ! 486: if (!isalnum(*s)) ! 487: break; ! 488: return *s == '='; ! 489: } ! 490: ! 491: #define MAXEXPON 38 /* maximum exponent for fp number */ ! 492: ! 493: isnumber(s) ! 494: register uchar *s; ! 495: { ! 496: register d1, d2; ! 497: int point; ! 498: uchar *es; ! 499: ! 500: d1 = d2 = point = 0; ! 501: while (*s == ' ' || *s == '\t' || *s == '\n') ! 502: s++; ! 503: if (*s == '\0') ! 504: return(0); /* empty stuff isn't number */ ! 505: if (*s == '+' || *s == '-') ! 506: s++; ! 507: if (!isdigit(*s) && *s != '.') ! 508: return(0); ! 509: if (isdigit(*s)) { ! 510: do { ! 511: d1++; ! 512: s++; ! 513: } while (isdigit(*s)); ! 514: } ! 515: if(d1 >= MAXEXPON) ! 516: return(0); /* too many digits to convert */ ! 517: if (*s == '.') { ! 518: point++; ! 519: s++; ! 520: } ! 521: if (isdigit(*s)) { ! 522: d2++; ! 523: do { ! 524: s++; ! 525: } while (isdigit(*s)); ! 526: } ! 527: if (!(d1 || point && d2)) ! 528: return(0); ! 529: if (*s == 'e' || *s == 'E') { ! 530: s++; ! 531: if (*s == '+' || *s == '-') ! 532: s++; ! 533: if (!isdigit(*s)) ! 534: return(0); ! 535: es = s; ! 536: do { ! 537: s++; ! 538: } while (isdigit(*s)); ! 539: if (s - es > 2) ! 540: return(0); ! 541: else if (s - es == 2 && 10 * (*es-'0') + *(es+1)-'0' >= MAXEXPON) ! 542: return(0); ! 543: } ! 544: while (*s == ' ' || *s == '\t' || *s == '\n') ! 545: s++; ! 546: if (*s == '\0') ! 547: return(1); ! 548: else ! 549: return(0); ! 550: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.