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