1*6678Smckusick /* tran.c 4.1 82/05/07 */ 2*6678Smckusick 3*6678Smckusick #include "stdio.h" 4*6678Smckusick #include "awk.def" 5*6678Smckusick #include "awk.h" 6*6678Smckusick 7*6678Smckusick cell *symtab[MAXSYM]; /* symbol table pointers */ 8*6678Smckusick 9*6678Smckusick char **FS; /* initial field sep */ 10*6678Smckusick char **RS; /* initial record sep */ 11*6678Smckusick char **OFS; /* output field sep */ 12*6678Smckusick char **ORS; /* output record sep */ 13*6678Smckusick char **OFMT; /*output format for numbers*/ 14*6678Smckusick awkfloat *NF; /* number of fields in current record */ 15*6678Smckusick awkfloat *NR; /* number of current record */ 16*6678Smckusick char **FILENAME; /* current filename argument */ 17*6678Smckusick 18*6678Smckusick cell *recloc; /* location of record */ 19*6678Smckusick cell *nrloc; /* NR */ 20*6678Smckusick cell *nfloc; /* NF */ 21*6678Smckusick 22*6678Smckusick syminit() 23*6678Smckusick { 24*6678Smckusick setsymtab("0", tostring("0"), 0.0, NUM|STR|CON|FLD, symtab); 25*6678Smckusick /* this one is used for if(x)... tests: */ 26*6678Smckusick setsymtab("$zero&null", tostring(""), 0.0, NUM|STR|CON|FLD, symtab); 27*6678Smckusick recloc = setsymtab("$record", record, 0.0, STR|FLD, symtab); 28*6678Smckusick dprintf("recloc %o lookup %o\n", recloc, lookup("$record", symtab, 0), NULL); 29*6678Smckusick FS = &setsymtab("FS", tostring(" "), 0.0, STR|FLD, symtab)->sval; 30*6678Smckusick RS = &setsymtab("RS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; 31*6678Smckusick OFS = &setsymtab("OFS", tostring(" "), 0.0, STR|FLD, symtab)->sval; 32*6678Smckusick ORS = &setsymtab("ORS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; 33*6678Smckusick OFMT = &setsymtab("OFMT", tostring("%.6g"), 0.0, STR|FLD, symtab)->sval; 34*6678Smckusick FILENAME = &setsymtab("FILENAME", NULL, 0.0, STR|FLD, symtab)->sval; 35*6678Smckusick nfloc = setsymtab("NF", NULL, 0.0, NUM, symtab); 36*6678Smckusick NF = &nfloc->fval; 37*6678Smckusick nrloc = setsymtab("NR", NULL, 0.0, NUM, symtab); 38*6678Smckusick NR = &nrloc->fval; 39*6678Smckusick } 40*6678Smckusick 41*6678Smckusick cell **makesymtab() 42*6678Smckusick { 43*6678Smckusick int i; 44*6678Smckusick cell **cp; 45*6678Smckusick 46*6678Smckusick cp = (cell **) malloc(MAXSYM * sizeof(cell *)); 47*6678Smckusick if (cp == NULL) 48*6678Smckusick error(FATAL, "out of space in makesymtab"); 49*6678Smckusick for (i = 0; i < MAXSYM; i++) 50*6678Smckusick cp[i] = 0; 51*6678Smckusick return(cp); 52*6678Smckusick } 53*6678Smckusick 54*6678Smckusick freesymtab(ap) /* free symbol table */ 55*6678Smckusick cell *ap; 56*6678Smckusick { 57*6678Smckusick cell *cp, **tp; 58*6678Smckusick int i; 59*6678Smckusick 60*6678Smckusick if (!(ap->tval & ARR)) 61*6678Smckusick return; 62*6678Smckusick tp = (cell **) ap->sval; 63*6678Smckusick for (i = 0; i < MAXSYM; i++) { 64*6678Smckusick for (cp = tp[i]; cp != NULL; cp = cp->nextval) { 65*6678Smckusick xfree(cp->nval); 66*6678Smckusick xfree(cp->sval); 67*6678Smckusick free(cp); 68*6678Smckusick } 69*6678Smckusick } 70*6678Smckusick xfree(tp); 71*6678Smckusick } 72*6678Smckusick 73*6678Smckusick cell *setsymtab(n, s, f, t, tab) 74*6678Smckusick char *n, *s; 75*6678Smckusick awkfloat f; 76*6678Smckusick unsigned t; 77*6678Smckusick cell **tab; 78*6678Smckusick { 79*6678Smckusick register h; 80*6678Smckusick register cell *p; 81*6678Smckusick cell *lookup(); 82*6678Smckusick 83*6678Smckusick if (n != NULL && (p = lookup(n, tab, 0)) != NULL) { 84*6678Smckusick xfree(s); 85*6678Smckusick dprintf("setsymtab found %o: %s", p, p->nval, NULL); 86*6678Smckusick dprintf(" %s %g %o\n", p->sval, p->fval, p->tval); 87*6678Smckusick return(p); 88*6678Smckusick } 89*6678Smckusick p = (cell *) malloc(sizeof(cell)); 90*6678Smckusick if (p == NULL) 91*6678Smckusick error(FATAL, "symbol table overflow at %s", n); 92*6678Smckusick p->nval = tostring(n); 93*6678Smckusick p->sval = s; 94*6678Smckusick p->fval = f; 95*6678Smckusick p->tval = t; 96*6678Smckusick h = hash(n); 97*6678Smckusick p->nextval = tab[h]; 98*6678Smckusick tab[h] = p; 99*6678Smckusick dprintf("setsymtab set %o: %s", p, p->nval, NULL); 100*6678Smckusick dprintf(" %s %g %o\n", p->sval, p->fval, p->tval); 101*6678Smckusick return(p); 102*6678Smckusick } 103*6678Smckusick 104*6678Smckusick hash(s) /* form hash value for string s */ 105*6678Smckusick register unsigned char *s; 106*6678Smckusick { 107*6678Smckusick register int hashval; 108*6678Smckusick 109*6678Smckusick for (hashval = 0; *s != '\0'; ) 110*6678Smckusick hashval += *s++; 111*6678Smckusick return(hashval % MAXSYM); 112*6678Smckusick } 113*6678Smckusick 114*6678Smckusick cell *lookup(s, tab, flag) /* look for s in tab, flag must match*/ 115*6678Smckusick register char *s; 116*6678Smckusick cell **tab; 117*6678Smckusick { 118*6678Smckusick register cell *p; 119*6678Smckusick 120*6678Smckusick for (p = tab[hash(s)]; p != NULL; p = p->nextval) 121*6678Smckusick if (strcmp(s, p->nval) == 0 && 122*6678Smckusick (flag == 0 || flag == p->tval)) 123*6678Smckusick return(p); /* found it */ 124*6678Smckusick return(NULL); /* not found */ 125*6678Smckusick } 126*6678Smckusick 127*6678Smckusick awkfloat setfval(vp, f) 128*6678Smckusick register cell *vp; 129*6678Smckusick awkfloat f; 130*6678Smckusick { 131*6678Smckusick dprintf("setfval: %o %g\n", vp, f, NULL); 132*6678Smckusick checkval(vp); 133*6678Smckusick if (vp == recloc) 134*6678Smckusick error(FATAL, "can't set $0"); 135*6678Smckusick vp->tval &= ~STR; /* mark string invalid */ 136*6678Smckusick vp->tval |= NUM; /* mark number ok */ 137*6678Smckusick if ((vp->tval & FLD) && vp->nval == 0) 138*6678Smckusick donerec = 0; 139*6678Smckusick return(vp->fval = f); 140*6678Smckusick } 141*6678Smckusick 142*6678Smckusick char *setsval(vp, s) 143*6678Smckusick register cell *vp; 144*6678Smckusick char *s; 145*6678Smckusick { 146*6678Smckusick dprintf("setsval: %o %s\n", vp, s, NULL); 147*6678Smckusick checkval(vp); 148*6678Smckusick if (vp == recloc) 149*6678Smckusick error(FATAL, "can't set $0"); 150*6678Smckusick vp->tval &= ~NUM; 151*6678Smckusick vp->tval |= STR; 152*6678Smckusick if ((vp->tval & FLD) && vp->nval == 0) 153*6678Smckusick donerec = 0; 154*6678Smckusick if (!(vp->tval&FLD)) 155*6678Smckusick xfree(vp->sval); 156*6678Smckusick vp->tval &= ~FLD; 157*6678Smckusick return(vp->sval = tostring(s)); 158*6678Smckusick } 159*6678Smckusick 160*6678Smckusick awkfloat getfval(vp) 161*6678Smckusick register cell *vp; 162*6678Smckusick { 163*6678Smckusick 164*6678Smckusick if (vp->sval == record && donerec == 0) 165*6678Smckusick recbld(); 166*6678Smckusick dprintf("getfval: %o", vp, NULL, NULL); 167*6678Smckusick checkval(vp); 168*6678Smckusick if ((vp->tval & NUM) == 0) { 169*6678Smckusick /* the problem is to make non-numeric things */ 170*6678Smckusick /* have unlikely numeric variables, so that */ 171*6678Smckusick /* $1 == $2 comparisons sort of make sense when */ 172*6678Smckusick /* one or the other is numeric */ 173*6678Smckusick if (isnumber(vp->sval)) { 174*6678Smckusick vp->fval = atof(vp->sval); 175*6678Smckusick if (!(vp->tval & CON)) /* don't change type of a constant */ 176*6678Smckusick vp->tval |= NUM; 177*6678Smckusick } 178*6678Smckusick else 179*6678Smckusick vp->fval = 0.0; /* not a very good idea */ 180*6678Smckusick } 181*6678Smckusick dprintf(" %g\n", vp->fval, NULL, NULL); 182*6678Smckusick return(vp->fval); 183*6678Smckusick } 184*6678Smckusick 185*6678Smckusick char *getsval(vp) 186*6678Smckusick register cell *vp; 187*6678Smckusick { 188*6678Smckusick char s[100]; 189*6678Smckusick 190*6678Smckusick if (vp->sval == record && donerec == 0) 191*6678Smckusick recbld(); 192*6678Smckusick dprintf("getsval: %o", vp, NULL, NULL); 193*6678Smckusick checkval(vp); 194*6678Smckusick if ((vp->tval & STR) == 0) { 195*6678Smckusick if (!(vp->tval&FLD)) 196*6678Smckusick xfree(vp->sval); 197*6678Smckusick if ((long)vp->fval==vp->fval) 198*6678Smckusick sprintf(s, "%.20g", vp->fval); 199*6678Smckusick else 200*6678Smckusick sprintf(s, *OFMT, vp->fval); 201*6678Smckusick vp->sval = tostring(s); 202*6678Smckusick vp->tval &= ~FLD; 203*6678Smckusick vp->tval |= STR; 204*6678Smckusick } 205*6678Smckusick dprintf(" %s\n", vp->sval, NULL, NULL); 206*6678Smckusick return(vp->sval); 207*6678Smckusick } 208*6678Smckusick 209*6678Smckusick checkval(vp) 210*6678Smckusick register cell *vp; 211*6678Smckusick { 212*6678Smckusick if (vp->tval & ARR) 213*6678Smckusick error(FATAL, "illegal reference to array %s", vp->nval); 214*6678Smckusick if ((vp->tval & (NUM | STR)) == 0) 215*6678Smckusick error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval, 216*6678Smckusick vp->sval, vp->fval, vp->tval); 217*6678Smckusick } 218*6678Smckusick 219*6678Smckusick char *tostring(s) 220*6678Smckusick register char *s; 221*6678Smckusick { 222*6678Smckusick register char *p; 223*6678Smckusick 224*6678Smckusick p = malloc(strlen(s)+1); 225*6678Smckusick if (p == NULL) 226*6678Smckusick error(FATAL, "out of space in tostring on %s", s); 227*6678Smckusick strcpy(p, s); 228*6678Smckusick return(p); 229*6678Smckusick } 230*6678Smckusick #ifndef yfree 231*6678Smckusick yfree(a) char *a; 232*6678Smckusick { 233*6678Smckusick printf("%o\n", a); 234*6678Smckusick free(a); 235*6678Smckusick } 236*6678Smckusick #endif 237*6678Smckusick #ifdef malloc 238*6678Smckusick #undef malloc 239*6678Smckusick char *ymalloc(u) unsigned u; 240*6678Smckusick { char *p; 241*6678Smckusick p = malloc(u); 242*6678Smckusick printf("%o %o\n", u, p); 243*6678Smckusick return(p); 244*6678Smckusick } 245*6678Smckusick #endif 246