1: #ifndef lint 2: static char sccsid[] = "@(#)tran.c 4.4 12/9/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