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