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