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