V10/cmd/PDP11/fpp/rhsymtab.c

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

/*
 *  mjm: calloc() -> kalloc() so no conflict with Unix calloc();
 *	and kalloc() calls malloc; also new OUT
 */
#define UNDEF (undefin)
#define NOTFOUND (-1)
#define OUT (0)		/* mjm: out of storage for malloc() */
#define PUTOK 1
#define PUTBAD 0
#define SYNAMEL 8
#define AREASIZN (504/sizeof(dummynode))
#define AREASIZE sizeof(**ixb)
static struct node {
	int lefta,leftn;
	int righta,rightn;
	int value;
	char nn[SYNAMEL];
	} dummynode;
static struct area {
	int areaname;
	int altered;
	struct node nodes[AREASIZN];
	};

struct head {
	int nodenew,areanew,lvalid;
	int lstart;
	struct head *lnext;
	};

static struct area *buff,**ixb;
static struct head *lhead;
static int fp;
static int oldlv;
/* the value to return for undefined symbol, set in rhccomp.c */
extern int undefin;
extern char *symtout;
extern int outcore;

/* return the value of a symbol s, starting from area a */
static getval(s,a)
struct area *a;
char *s;
{
int n,c,at;
	n=0;
	while(c=sycomp(s,a->nodes[n].nn)) {
		if(c<0) {
			if((at=a->nodes[n].lefta)==0) return(NOTFOUND);
			n=a->nodes[n].leftn;
			}
		else {
			if((at=a->nodes[n].righta)==0) return(NOTFOUND);
			n=a->nodes[n].rightn;
			}
		if(at!=a->areaname) a=fetcha(at);
		}
	return(a->nodes[n].value);
}

/* define a symbol s with value v starting in area a */
static putval(s,a,v)
int v;
struct area *a;
char *s;
{
int n,c,at;
	n=0;
	while(c=sycomp(s,a->nodes[n].nn)) {
		if(c<0) {
			if((at=a->nodes[n].lefta)==0) {
				return(putlink(s,a,v,n,'l'));
				}
			n=a->nodes[n].leftn;
			}
		else {
			if((at=a->nodes[n].righta)==0) {
				return(putlink(s,a,v,n,'r'));
				}
			n=a->nodes[n].rightn;
			}
		if(at!=a->areaname) a=fetcha(at);
		}
	return(PUTBAD);
}

/* initial call here: set up size in bytes of symtab buffers */
symtab(size)
int size;
{
int i;
	buff=kalloc(size);
	ixb=kalloc(2*sizeof(buff)+(sizeof(buff)*size)/AREASIZE);	/* mjm: 2->sizeof */
	if((fp=creat(symtout,0666))<0) abt("can't create file for symtab");
	close(fp);
	if((fp=open(symtout,2))<0) abt("can't re-open file for symtab");
	lhead=kalloc(sizeof(*lhead));
	lhead->lnext = lhead->nodenew = lhead->lvalid = 0;
	lhead->lstart=lhead->areanew=1;
	oldlv=0;
	for(i=0; AREASIZE*(i+1)<=size; i++) {
		ixb[i]= &buff[i];
		buff[i].areaname=0; buff[i].altered=0;
		}
	ixb[i]=0;
}

/* define the current level of symbol definition */
definelv(lv)
int lv;
{
struct head *lnew;
if(lv>oldlv) {
	lnew=kalloc(sizeof(*lhead));
	lnew->lnext=lhead;
	if(lhead->nodenew) {
		lnew->areanew=lhead->areanew+1;
		}
	else {
		lnew->areanew=lhead->areanew;
		}
	lnew->nodenew=lnew->lvalid=0;
	lnew->lstart=lnew->areanew;
	lhead=lnew;
	}
if(lv<oldlv) {
	lnew=lhead->lnext;
	free(lhead);
	lhead=lnew;
	}
oldlv=lv;
}

/* define a symbol */
definesy(s,v)
char *s;
int v;
{
struct area *a;
	if(lhead->lvalid) return(putval(s,fetcha(lhead->lstart),v));
	else {
		lhead->lvalid=1;
		lhead->nodenew=1;
		a=fetcha(lhead->lstart);
		return(putnv(s,a,v,0));
		}
}

/* get a symbol value at current level or below */
gettype(s)
char *s;
{
struct head *h;
int i;
	h=lhead;
	while(h) {
		if(h->lvalid)
			if((i=getval(s,fetcha(h->lstart)))!=NOTFOUND)return(i);
		h=h->lnext;
		}
	return(UNDEF);
}
static putnv(s,a,v,n) /* put a new node at n in a */
int v,n;
struct area *a;
char *s;
{
struct node *nq;
int i;
char *s2;
	a->altered=1;
	s2=(nq= &a->nodes[n])->nn;
	i=0;
	while(i++<SYNAMEL&&(*s2++= *s++));
	nq->lefta=nq->righta=0;
	nq->value=v;
	return(PUTOK);
}

static putlink(s,a,v,n,lr)	/* put new node and link to ... */
char *s;
struct area *a;
int v,n,lr;
{
	a->altered=1;
	if(lr=='l') {
		a->nodes[n].leftn=lhead->nodenew;
		a->nodes[n].lefta=lhead->areanew;
		}
	else {
		a->nodes[n].rightn=lhead->nodenew;
		a->nodes[n].righta=lhead->areanew;
		}
        a=fetcha(lhead->areanew);
	putnv(s,a,v,lhead->nodenew);
	if(++lhead->nodenew>=AREASIZN) {
		lhead->nodenew=0;
		lhead->areanew++;
		}
	return(PUTOK);
}

/* check out strings */
static sycomp(s1,s2)
char *s1,*s2;
{
int i;
for(i=0; i<SYNAMEL&&(*s1||*s2); i++)
	if(*s1++!= *s2++)
		return(*--s1- *--s2);
return(0);
}

/* dynamic disk reader-writer */
static fetcha(ta)
int ta;
{
struct area *it;
int i;
long lonk;
	for(i=0; it=ixb[i]; i++)
		if(it->areaname==ta) break;
	if(it==0) {
		it= ixb[--i];
		if(it->altered) {
			lseek(fp,(lonk=it->areaname)<<9,0);
			write(fp,it,AREASIZE);
			}
		lseek(fp,(lonk=ta)<<9,0);
		read(fp,it,AREASIZE);
		it->altered=0;
		it->areaname=ta;
		}
        while(i-->0) ixb[i+1]=ixb[i];
	return(*ixb=it);
}

static kalloc(sz)
int sz;
{	/* mjm: made malloc arg always even */
if((sz=malloc((sz+1)&~01)) != OUT)
	return(sz);
abt("out of storage in symtab");
}