1: #include "stdio.h" 2: #include "awk.def" 3: #include "awk.h" 4: #include "ctype.h" 5: 6: FILE *infile = NULL; 7: char *file; 8: #define RECSIZE 512 9: char record[RECSIZE]; 10: char fields[RECSIZE]; 11: char EMPTY[] = ""; 12: 13: #define MAXFLD 50 14: int donefld; /* 1 = implies rec broken into fields */ 15: int donerec; /* 1 = record is valid (no flds have changed) */ 16: int mustfld; /* 1 = NF seen, so always break*/ 17: 18: #define FINIT {0, NULL, 0.0, FLD|STR} 19: cell fldtab[MAXFLD] = { /*room for fields */ 20: { "$record", record, 0.0, STR|FLD}, 21: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, 22: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, 23: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, 24: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, 25: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, 26: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, 27: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT 28: }; 29: int maxfld = 0; /* last used field */ 30: 31: 32: getrec() 33: { 34: register char *rr; 35: extern int svargc; 36: extern char **svargv; 37: register c, sep; 38: 39: dprintf("**RS=%o, **FS=%o\n", **RS, **FS, NULL); 40: donefld = 0; 41: donerec = 1; 42: record[0] = 0; 43: while (svargc > 0) { 44: dprintf("svargc=%d, *svargv=%s\n", svargc, *svargv, NULL); 45: if (infile == NULL) { /* have to open a new file */ 46: if (member('=', *svargv)) { /* it's a var=value argument */ 47: setclvar(*svargv); 48: svargv++; 49: svargc--; 50: continue; 51: } 52: *FILENAME = file = *svargv; 53: dprintf("opening file %s\n", file, NULL, NULL); 54: if (*file == '-') 55: infile = stdin; 56: else if ((infile = fopen(file, "r")) == NULL) 57: error(FATAL, "can't open %s", file); 58: } 59: if ((sep = **RS) == 0) 60: sep = '\n'; 61: for (rr = record; ; ) { 62: for (; (c=getc(infile)) != sep && c != EOF; *rr++ = c) 63: ; 64: if (**RS == sep || c == EOF) 65: break; 66: if ((c = getc(infile)) == '\n' || c == EOF) /* 2 in a row */ 67: break; 68: *rr++ = '\n'; 69: *rr++ = c; 70: } 71: if (rr > record+RECSIZE) 72: error(FATAL, "record `%.20s...' too long", record); 73: *rr = 0; 74: if (mustfld) 75: fldbld(); 76: if (c != EOF) /* normal record */ 77: return(1); 78: /* EOF arrived on this file; set up next */ 79: if (infile != stdin) 80: fclose(infile); 81: infile = NULL; 82: svargc--; 83: svargv++; 84: } 85: return(0); /* true end of file */ 86: } 87: 88: setclvar(s) /* set var=value from s */ 89: char *s; 90: { 91: char *p; 92: cell *q; 93: 94: for (p=s; *p != '='; p++) 95: ; 96: *p++ = 0; 97: q = setsymtab(s, tostring(p), 0.0, STR, symtab); 98: setsval(q, p); 99: dprintf("command line set %s to |%s|\n", s, p, NULL); 100: } 101: 102: fldbld() 103: { 104: register char *r, *fr, sep; 105: int i, j; 106: 107: r = record; 108: fr = fields; 109: if ((sep = **FS) == ' ') 110: for (i = 0; ; ) { 111: while (*r == ' ' || *r == '\t' || *r == '\n') 112: r++; 113: if (*r == 0) 114: break; 115: i++; 116: if (i >= MAXFLD) 117: error(FATAL, "record `%.20s...' has too many fields", record); 118: if (!(fldtab[i].tval&FLD)) 119: xfree(fldtab[i].sval); 120: fldtab[i].sval = fr; 121: fldtab[i].tval = FLD | STR; 122: do 123: *fr++ = *r++; 124: while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0'); 125: *fr++ = 0; 126: } 127: else 128: for (i = 0; ; ) { 129: i++; 130: if (i >= MAXFLD) 131: error(FATAL, "record `%.20s...' has too many fields", record); 132: if (!(fldtab[i].tval&FLD)) 133: xfree(fldtab[i].sval); 134: fldtab[i].sval = fr; 135: fldtab[i].tval = FLD | STR; 136: while (*r != sep && *r != '\n' && *r != '\0') /* \n always a separator */ 137: *fr++ = *r++; 138: *fr++ = '\0'; 139: if (*r == 0) break; 140: r++; 141: } 142: *fr = 0; 143: for (j=maxfld; j>i; j--) { /* clean out junk from previous record */ 144: if (!(fldtab[j].tval&FLD)) 145: xfree(fldtab[j].sval); 146: fldtab[j].tval = STR | FLD; 147: fldtab[j].sval = NULL; 148: } 149: maxfld = i; 150: donefld = 1; 151: for(i=1; i<=maxfld; i++) 152: if(isnumber(fldtab[i].sval)) 153: { fldtab[i].fval = atof(fldtab[i].sval); 154: fldtab[i].tval |= NUM; 155: } 156: setfval(lookup("NF", symtab), (awkfloat) maxfld); 157: if (dbg) 158: for (i = 0; i <= maxfld; i++) 159: printf("field %d: |%s|\n", i, fldtab[i].sval); 160: } 161: 162: recbld() 163: { 164: int i; 165: register char *r, *p; 166: 167: if (donefld == 0 || donerec == 1) 168: return; 169: r = record; 170: for (i = 1; i <= *NF; i++) { 171: p = getsval(&fldtab[i]); 172: while (*r++ = *p++) 173: ; 174: *(r-1) = **OFS; 175: } 176: *(r-1) = '\0'; 177: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL); 178: recloc->tval = STR | FLD; 179: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL); 180: if (r > record+RECSIZE) 181: error(FATAL, "built giant record `%.20s...'", record); 182: dprintf("recbld = |%s|\n", record, NULL, NULL); 183: } 184: 185: cell *fieldadr(n) 186: { 187: if (n >= MAXFLD) 188: error(FATAL, "trying to access field %d", n); 189: return(&fldtab[n]); 190: } 191: 192: int errorflag = 0; 193: 194: yyerror(s) char *s; { 195: fprintf(stderr, "awk: %s near line %d\n", s, lineno); 196: errorflag = 2; 197: } 198: 199: error(f, s, a1, a2, a3, a4, a5, a6, a7) { 200: fprintf(stderr, "awk: "); 201: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 202: fprintf(stderr, "\n"); 203: if (*NR > 0) 204: fprintf(stderr, " record number %g\n", *NR); 205: if (f) 206: exit(2); 207: } 208: 209: PUTS(s) char *s; { 210: dprintf("%s\n", s, NULL, NULL); 211: } 212: 213: #define MAXEXPON 38 /* maximum exponenet for fp number */ 214: 215: isnumber(s) 216: register char *s; 217: { 218: register d1, d2; 219: int point; 220: char *es; 221: 222: d1 = d2 = point = 0; 223: while (*s == ' ' || *s == '\t' || *s == '\n') 224: s++; 225: if (*s == '\0') 226: return(0); /* empty stuff isn't number */ 227: if (*s == '+' || *s == '-') 228: s++; 229: if (!isdigit(*s) && *s != '.') 230: return(0); 231: if (isdigit(*s)) { 232: d1++; 233: do { 234: s++; 235: } while (isdigit(*s)); 236: } 237: if (*s == '.') { 238: point++; 239: s++; 240: } 241: if (d1 == 0 && point == 0) 242: return(0); 243: if (isdigit(*s)) { 244: d2++; 245: do { 246: s++; 247: } while (isdigit(*s)); 248: } 249: if (!(d1 || point && d2)) 250: return(0); 251: if (*s == 'e' || *s == 'E') { 252: s++; 253: if (*s == '+' || *s == '-') 254: s++; 255: if (!isdigit(*s)) 256: return(0); 257: es = s; 258: do { 259: s++; 260: } while (isdigit(*s)); 261: if (s - es > 2) 262: return(0); 263: else if (s - es == 2 && 10 * (*es-'0') + *(es+1)-'0' >= MAXEXPON) 264: return(0); 265: } 266: while (*s == ' ' || *s == '\t' || *s == '\n') 267: s++; 268: if (*s == '\0') 269: return(1); 270: else 271: return(0); 272: } 273: /* 274: isnumber(s) char *s; {return(0);} 275: */