V8/usr/src/cmd/awk/tran.c

Compare this file to the similar file:
Show the results in this format:

#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