|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)tran.c 4.3 8/11/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) && vp->nval == 0) ! 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) && vp->nval == 0) ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.