1*10795Ssam /* tran.c 4.2 83/02/09 */ 26678Smckusick 36678Smckusick #include "stdio.h" 46678Smckusick #include "awk.def" 56678Smckusick #include "awk.h" 66678Smckusick 76678Smckusick cell *symtab[MAXSYM]; /* symbol table pointers */ 86678Smckusick 96678Smckusick char **FS; /* initial field sep */ 106678Smckusick char **RS; /* initial record sep */ 116678Smckusick char **OFS; /* output field sep */ 126678Smckusick char **ORS; /* output record sep */ 136678Smckusick char **OFMT; /*output format for numbers*/ 146678Smckusick awkfloat *NF; /* number of fields in current record */ 156678Smckusick awkfloat *NR; /* number of current record */ 166678Smckusick char **FILENAME; /* current filename argument */ 176678Smckusick 186678Smckusick cell *recloc; /* location of record */ 196678Smckusick cell *nrloc; /* NR */ 206678Smckusick cell *nfloc; /* NF */ 216678Smckusick 226678Smckusick syminit() 236678Smckusick { 246678Smckusick setsymtab("0", tostring("0"), 0.0, NUM|STR|CON|FLD, symtab); 256678Smckusick /* this one is used for if(x)... tests: */ 266678Smckusick setsymtab("$zero&null", tostring(""), 0.0, NUM|STR|CON|FLD, symtab); 276678Smckusick recloc = setsymtab("$record", record, 0.0, STR|FLD, symtab); 286678Smckusick dprintf("recloc %o lookup %o\n", recloc, lookup("$record", symtab, 0), NULL); 296678Smckusick FS = &setsymtab("FS", tostring(" "), 0.0, STR|FLD, symtab)->sval; 306678Smckusick RS = &setsymtab("RS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; 316678Smckusick OFS = &setsymtab("OFS", tostring(" "), 0.0, STR|FLD, symtab)->sval; 326678Smckusick ORS = &setsymtab("ORS", tostring("\n"), 0.0, STR|FLD, symtab)->sval; 336678Smckusick OFMT = &setsymtab("OFMT", tostring("%.6g"), 0.0, STR|FLD, symtab)->sval; 34*10795Ssam FILENAME = &setsymtab("FILENAME", EMPTY, 0.0, STR|FLD, symtab)->sval; 35*10795Ssam nfloc = setsymtab("NF", EMPTY, 0.0, NUM, symtab); 366678Smckusick NF = &nfloc->fval; 37*10795Ssam nrloc = setsymtab("NR", EMPTY, 0.0, NUM, symtab); 386678Smckusick NR = &nrloc->fval; 396678Smckusick } 406678Smckusick 416678Smckusick cell **makesymtab() 426678Smckusick { 436678Smckusick int i; 446678Smckusick cell **cp; 456678Smckusick 466678Smckusick cp = (cell **) malloc(MAXSYM * sizeof(cell *)); 476678Smckusick if (cp == NULL) 486678Smckusick error(FATAL, "out of space in makesymtab"); 496678Smckusick for (i = 0; i < MAXSYM; i++) 506678Smckusick cp[i] = 0; 516678Smckusick return(cp); 526678Smckusick } 536678Smckusick 546678Smckusick freesymtab(ap) /* free symbol table */ 556678Smckusick cell *ap; 566678Smckusick { 576678Smckusick cell *cp, **tp; 586678Smckusick int i; 596678Smckusick 606678Smckusick if (!(ap->tval & ARR)) 616678Smckusick return; 626678Smckusick tp = (cell **) ap->sval; 636678Smckusick for (i = 0; i < MAXSYM; i++) { 646678Smckusick for (cp = tp[i]; cp != NULL; cp = cp->nextval) { 65*10795Ssam strfree(cp->nval); 66*10795Ssam strfree(cp->sval); 676678Smckusick free(cp); 686678Smckusick } 696678Smckusick } 706678Smckusick xfree(tp); 716678Smckusick } 726678Smckusick 736678Smckusick cell *setsymtab(n, s, f, t, tab) 746678Smckusick char *n, *s; 756678Smckusick awkfloat f; 766678Smckusick unsigned t; 776678Smckusick cell **tab; 786678Smckusick { 796678Smckusick register h; 806678Smckusick register cell *p; 816678Smckusick cell *lookup(); 826678Smckusick 836678Smckusick if (n != NULL && (p = lookup(n, tab, 0)) != NULL) { 84*10795Ssam if (s != EMPTY ) xfree(s); /* careful here */ 856678Smckusick dprintf("setsymtab found %o: %s", p, p->nval, NULL); 866678Smckusick dprintf(" %s %g %o\n", p->sval, p->fval, p->tval); 876678Smckusick return(p); 886678Smckusick } 896678Smckusick p = (cell *) malloc(sizeof(cell)); 906678Smckusick if (p == NULL) 916678Smckusick error(FATAL, "symbol table overflow at %s", n); 926678Smckusick p->nval = tostring(n); 936678Smckusick p->sval = s; 946678Smckusick p->fval = f; 956678Smckusick p->tval = t; 966678Smckusick h = hash(n); 976678Smckusick p->nextval = tab[h]; 986678Smckusick tab[h] = p; 996678Smckusick dprintf("setsymtab set %o: %s", p, p->nval, NULL); 1006678Smckusick dprintf(" %s %g %o\n", p->sval, p->fval, p->tval); 1016678Smckusick return(p); 1026678Smckusick } 1036678Smckusick 1046678Smckusick hash(s) /* form hash value for string s */ 1056678Smckusick register unsigned char *s; 1066678Smckusick { 1076678Smckusick register int hashval; 1086678Smckusick 1096678Smckusick for (hashval = 0; *s != '\0'; ) 1106678Smckusick hashval += *s++; 1116678Smckusick return(hashval % MAXSYM); 1126678Smckusick } 1136678Smckusick 1146678Smckusick cell *lookup(s, tab, flag) /* look for s in tab, flag must match*/ 1156678Smckusick register char *s; 1166678Smckusick cell **tab; 1176678Smckusick { 1186678Smckusick register cell *p; 1196678Smckusick 1206678Smckusick for (p = tab[hash(s)]; p != NULL; p = p->nextval) 1216678Smckusick if (strcmp(s, p->nval) == 0 && 1226678Smckusick (flag == 0 || flag == p->tval)) 1236678Smckusick return(p); /* found it */ 1246678Smckusick return(NULL); /* not found */ 1256678Smckusick } 1266678Smckusick 1276678Smckusick awkfloat setfval(vp, f) 1286678Smckusick register cell *vp; 1296678Smckusick awkfloat f; 1306678Smckusick { 1316678Smckusick dprintf("setfval: %o %g\n", vp, f, NULL); 1326678Smckusick checkval(vp); 1336678Smckusick if (vp == recloc) 1346678Smckusick error(FATAL, "can't set $0"); 1356678Smckusick vp->tval &= ~STR; /* mark string invalid */ 1366678Smckusick vp->tval |= NUM; /* mark number ok */ 1376678Smckusick if ((vp->tval & FLD) && vp->nval == 0) 1386678Smckusick donerec = 0; 1396678Smckusick return(vp->fval = f); 1406678Smckusick } 1416678Smckusick 1426678Smckusick char *setsval(vp, s) 1436678Smckusick register cell *vp; 1446678Smckusick char *s; 1456678Smckusick { 1466678Smckusick dprintf("setsval: %o %s\n", vp, s, NULL); 1476678Smckusick checkval(vp); 1486678Smckusick if (vp == recloc) 1496678Smckusick error(FATAL, "can't set $0"); 1506678Smckusick vp->tval &= ~NUM; 1516678Smckusick vp->tval |= STR; 1526678Smckusick if ((vp->tval & FLD) && vp->nval == 0) 1536678Smckusick donerec = 0; 1546678Smckusick if (!(vp->tval&FLD)) 155*10795Ssam strfree(vp->sval); 1566678Smckusick vp->tval &= ~FLD; 1576678Smckusick return(vp->sval = tostring(s)); 1586678Smckusick } 1596678Smckusick 1606678Smckusick awkfloat getfval(vp) 1616678Smckusick register cell *vp; 1626678Smckusick { 1636678Smckusick 1646678Smckusick if (vp->sval == record && donerec == 0) 1656678Smckusick recbld(); 1666678Smckusick dprintf("getfval: %o", vp, NULL, NULL); 1676678Smckusick checkval(vp); 1686678Smckusick if ((vp->tval & NUM) == 0) { 1696678Smckusick /* the problem is to make non-numeric things */ 1706678Smckusick /* have unlikely numeric variables, so that */ 1716678Smckusick /* $1 == $2 comparisons sort of make sense when */ 1726678Smckusick /* one or the other is numeric */ 1736678Smckusick if (isnumber(vp->sval)) { 1746678Smckusick vp->fval = atof(vp->sval); 1756678Smckusick if (!(vp->tval & CON)) /* don't change type of a constant */ 1766678Smckusick vp->tval |= NUM; 1776678Smckusick } 1786678Smckusick else 1796678Smckusick vp->fval = 0.0; /* not a very good idea */ 1806678Smckusick } 1816678Smckusick dprintf(" %g\n", vp->fval, NULL, NULL); 1826678Smckusick return(vp->fval); 1836678Smckusick } 1846678Smckusick 1856678Smckusick char *getsval(vp) 1866678Smckusick register cell *vp; 1876678Smckusick { 1886678Smckusick char s[100]; 1896678Smckusick 1906678Smckusick if (vp->sval == record && donerec == 0) 1916678Smckusick recbld(); 1926678Smckusick dprintf("getsval: %o", vp, NULL, NULL); 1936678Smckusick checkval(vp); 1946678Smckusick if ((vp->tval & STR) == 0) { 1956678Smckusick if (!(vp->tval&FLD)) 196*10795Ssam strfree(vp->sval); 1976678Smckusick if ((long)vp->fval==vp->fval) 1986678Smckusick sprintf(s, "%.20g", vp->fval); 1996678Smckusick else 2006678Smckusick sprintf(s, *OFMT, vp->fval); 2016678Smckusick vp->sval = tostring(s); 2026678Smckusick vp->tval &= ~FLD; 2036678Smckusick vp->tval |= STR; 2046678Smckusick } 2056678Smckusick dprintf(" %s\n", vp->sval, NULL, NULL); 2066678Smckusick return(vp->sval); 2076678Smckusick } 2086678Smckusick 2096678Smckusick checkval(vp) 2106678Smckusick register cell *vp; 2116678Smckusick { 2126678Smckusick if (vp->tval & ARR) 2136678Smckusick error(FATAL, "illegal reference to array %s", vp->nval); 2146678Smckusick if ((vp->tval & (NUM | STR)) == 0) 2156678Smckusick error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval, 2166678Smckusick vp->sval, vp->fval, vp->tval); 2176678Smckusick } 2186678Smckusick 2196678Smckusick char *tostring(s) 2206678Smckusick register char *s; 2216678Smckusick { 2226678Smckusick register char *p; 2236678Smckusick 224*10795Ssam if (s==NULL){ 225*10795Ssam p = malloc(1); 226*10795Ssam if (p == NULL) 227*10795Ssam error(FATAL, "out of space in tostring on %s", s); 228*10795Ssam *p = '\0'; 229*10795Ssam } else { 230*10795Ssam p = malloc(strlen(s)+1); 231*10795Ssam if (p == NULL) 232*10795Ssam error(FATAL, "out of space in tostring on %s", s); 233*10795Ssam strcpy(p, s); 234*10795Ssam } 2356678Smckusick return(p); 2366678Smckusick } 2376678Smckusick #ifndef yfree 2386678Smckusick yfree(a) char *a; 2396678Smckusick { 2406678Smckusick printf("%o\n", a); 2416678Smckusick free(a); 2426678Smckusick } 2436678Smckusick #endif 2446678Smckusick #ifdef malloc 2456678Smckusick #undef malloc 2466678Smckusick char *ymalloc(u) unsigned u; 2476678Smckusick { char *p; 2486678Smckusick p = malloc(u); 2496678Smckusick printf("%o %o\n", u, p); 2506678Smckusick return(p); 2516678Smckusick } 2526678Smckusick #endif 253