|
|
researchv8 Dan Cross
#define DEBUG
#include <stdio.h>
#include "awk.h"
#include "y.tab.h"
Cell *symtab[MAXSYM]; /* symbol table pointers */
char **FS; /* initial field sep */
char **RS; /* initial record sep */
char **OFS; /* output field sep */
char **ORS; /* output record sep */
char **OFMT; /*output format for numbers*/
Awkfloat *NF; /* number of fields in current record */
Awkfloat *NR; /* number of current record */
Awkfloat *FNR; /* number of current record in current file */
char **FILENAME; /* current filename argument */
Awkfloat *ARGC; /* number of arguments from command line */
Cell *recloc; /* location of record */
Cell *nrloc; /* NR */
Cell *nfloc; /* NF */
Cell *fnrloc; /* FNR */
Cell **ARGVtab; /* symbol table containing ARGV[...] */
syminit(ac, av)
char *av[];
{
arginit(ac, av);
setsymtab("0", "0", 0.0, NUM|STR|CON, symtab);
/* this one is used for if(x)... tests: */
setsymtab("$zero&null", "", 0.0, NUM|STR|CON, symtab);
recloc = setsymtab("$0", record, 0.0, REC|STR|DONTFREE, symtab);
dprintf("recloc %o lookup %o\n", recloc, lookup("$0", symtab), NULL);
FS = &setsymtab("FS", " ", 0.0, STR, symtab)->sval;
RS = &setsymtab("RS", "\n", 0.0, STR, symtab)->sval;
OFS = &setsymtab("OFS", " ", 0.0, STR, symtab)->sval;
ORS = &setsymtab("ORS", "\n", 0.0, STR, symtab)->sval;
OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR, symtab)->sval;
FILENAME = &setsymtab("FILENAME", "", 0.0, STR, symtab)->sval;
nfloc = setsymtab("NF", "", 0.0, NUM, symtab);
NF = &nfloc->fval;
nrloc = setsymtab("NR", "", 0.0, NUM, symtab);
NR = &nrloc->fval;
fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
FNR = &fnrloc->fval;
}
arginit(ac, av)
int ac;
char *av[];
{
Cell *cp, **makesymtab();
int i;
char temp[5];
ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
ARGVtab = makesymtab();
cp->sval = (char *) ARGVtab;
for (i = 0; i < ac; i++) {
sprintf(temp, "%d", i);
if (isnumber(*av))
setsymtab(temp, *av, atof(*av), STR|NUM, cp->sval);
else
setsymtab(temp, *av, 0.0, STR, cp->sval);
av++;
}
}
Cell **makesymtab()
{
Cell **cp;
cp = (Cell **) Calloc(MAXSYM, sizeof(Cell *));
if (cp == NULL)
error(FATAL, "out of space in makesymtab");
return(cp);
}
freesymtab(ap) /* free symbol table */
Cell *ap;
{
Cell *cp, **tp;
int i;
if (!isarr(ap))
return;
tp = (Cell **) ap->sval;
if (tp == NULL)
return;
for (i = 0; i < MAXSYM; i++) {
for (cp = tp[i]; cp != NULL; cp = cp->cnext) {
xfree(cp->nval);
xfree(cp->sval);
Free(cp);
}
}
xfree(tp);
}
freeelem(ap, s) /* free elem s from ap (i.e., ap["s"] */
Cell *ap;
char *s;
{
Cell **tab, *p, *prev = NULL;
int h;
tab = (Cell **) ap->sval;
h = hash(s);
for (p = tab[h]; p != NULL; prev = p, p = p->cnext)
if (strcmp(s, p->nval) == 0) {
if (prev == NULL) /* 1st one */
tab[h] = p->cnext;
else /* middle somewhere */
prev->cnext = p->cnext;
if (!(p->tval&DONTFREE))
xfree(p->sval);
Free(p->nval);
Free(p);
return;
}
}
Cell *setsymtab(n, s, f, t, tab)
char *n, *s;
Awkfloat f;
unsigned t;
Cell **tab;
{
register h;
register Cell *p;
Cell *lookup();
if (n != NULL && (p = lookup(n, tab)) != NULL) {
dprintf("setsymtab found %o: n=%s", p, p->nval, NULL);
dprintf(" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval);
return(p);
}
p = (Cell *) Malloc(sizeof(Cell));
if (p == NULL)
error(FATAL, "symbol table overflow at %s", n);
p->nval = tostring(n);
p->sval = s ? tostring(s) : tostring("");
p->fval = f;
p->tval = t;
h = hash(n);
p->cnext = tab[h];
tab[h] = p;
dprintf("setsymtab set %o: n=%s", p, p->nval, NULL);
dprintf(" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval);
return(p);
}
hash(s) /* form hash value for string s */
register unsigned char *s;
{
register int hashval;
for (hashval = 0; *s != '\0'; s++)
hashval = (*s + 31 * hashval) % MAXSYM;
return hashval;
}
Cell *lookup(s, tab) /* look for s in tab */
register char *s;
Cell **tab;
{
register Cell *p, *prev = NULL;
int h;
extern int indepth;
h = hash(s);
for (p = tab[h]; p != NULL; prev = p, p = p->cnext) {
if (strcmp(s, p->nval) == 0) {
if (prev != NULL && indepth == 0) {
prev->cnext = p->cnext;
p->cnext = tab[h];
tab[h] = p;
}
return(p); /* found it */
}
}
return(NULL); /* not found */
}
Awkfloat setfval(vp, f)
register Cell *vp;
Awkfloat f;
{
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
vp, vp->nval, vp->sval, vp->fval, vp->tval);
if (vp->tval & FLD) {
donerec = 0; /* mark $0 invalid */
} else if (vp->tval & REC) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
}
vp->tval &= ~STR; /* mark string invalid */
vp->tval |= NUM; /* mark number ok */
dprintf("setfval %o: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval);
return vp->fval = f;
}
char *setsval(vp, s)
register Cell *vp;
char *s;
{
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
vp, vp->nval, vp->sval, vp->fval, vp->tval);
if (vp->tval & FLD) {
donerec = 0; /* mark $0 invalid */
} else if (vp->tval & REC) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
}
vp->tval &= ~NUM;
vp->tval |= STR;
if (!(vp->tval&DONTFREE))
xfree(vp->sval);
vp->tval &= ~DONTFREE;
dprintf("setsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval);
return(vp->sval = tostring(s));
}
Awkfloat real_getfval(vp)
register Cell *vp;
{
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
vp, vp->nval, vp->sval, vp->fval, vp->tval);
if ((vp->tval & FLD) && donefld == 0)
fldbld();
else if ((vp->tval & REC) && donerec == 0)
recbld();
if (!isnum(vp)) { /* not a number */
vp->fval = atof(vp->sval); /* best guess */
if (isnumber(vp->sval) && !(vp->tval&CON))
vp->tval |= NUM; /* make NUM only sparingly */
}
dprintf("getfval %o: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval);
return(vp->fval);
}
char *real_getsval(vp)
register Cell *vp;
{
char s[100];
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
vp, vp->nval, vp->sval, vp->fval, vp->tval);
if ((vp->tval & FLD) && donefld == 0)
fldbld();
else if ((vp->tval & REC) && donerec == 0)
recbld();
if ((vp->tval & STR) == 0) {
if (!(vp->tval&DONTFREE))
xfree(vp->sval);
if ((long)vp->fval == vp->fval)
sprintf(s, "%.20g", vp->fval);
else
sprintf(s, *OFMT, vp->fval);
vp->sval = tostring(s);
vp->tval &= ~DONTFREE;
vp->tval |= STR;
}
dprintf("getsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, vp->sval, vp->tval);
return(vp->sval);
}
char *tostring(s)
register char *s;
{
register char *p;
p = Malloc(strlen(s)+1);
if (p == NULL)
error(FATAL, "out of space in tostring on %s", s);
strcpy(p, s);
return(p);
}
#ifdef MYALLOC
char *Malloc(n)
int n;
{
fprintf(stderr, "m %d\n", n);
return malloc(n);
}
char *Calloc(n, sz)
int n, sz;
{
fprintf(stderr, "c %d (%d %d)\n", n*sz, n, sz);
return calloc(n, sz);
}
Free(p)
char *p;
{
free(p);
}
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.