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