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