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