shithub: lpa

ref: 2b23d05d57743af57385cd42c0fd2d223b11d8c8
dir: /symtab.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>

#include "dat.h"
#include "fns.h"

Symtab *
allocsymtab(void)
{
	Symtab *s = alloc(DataSymtab);
	return s;
}

uvlong
sym(Symtab *s, char *name)
{
	uvlong id;
	int new = 1;
	rlock(&s->lock);
	for(id = 0; id < s->count; id++){
		if(strcmp(name, s->symbols[id]->name) == 0){
			new = 0;
			break;
		}
	}
	runlock(&s->lock);
	if(new){
		/* check if the name is valid, or return -1 */
		Symbol *newsym = alloc(DataSymbol);
		newsym->name = strdup(name);
		newsym->value = nil;
		newsym->qsymbol = freshobjqid();
		newsym->table = s;
		newsym->id = id;

		wlock(&s->lock);
		s->count++;
		s->symbols = allocextra(s, sizeof(Symbol *) * s->count);
		s->symbols[id] = newsym;
		wunlock(&s->lock);
	}
	return id;
}

char *
symname(Symtab *s, uvlong id)
{
	char *name;
	rlock(&s->lock);
	name = s->symbols[id]->name;
	runlock(&s->lock);
	return name;
}

void *
symval(Symtab *s, uvlong id)
{
	void *value;
	rlock(&s->lock);
	value = s->symbols[id]->value;
	runlock(&s->lock);
	return value;
}

Symbol *
symptr(Symtab *s, uvlong id)
{
	Symbol *symb;
	rlock(&s->lock);
	symb = s->symbols[id];
	runlock(&s->lock);
	return symb;
}

void
symset(Symtab *s, uvlong id, void *newval)
{
	wlock(&s->lock);
	s->symbols[id]->value = newval;
	s->symbols[id]->qsymbol.vers++;
	wunlock(&s->lock);
}

Enumeration *
enumsymbols(Symtab *symtab, int all)
{
	rlock(&symtab->lock);
	uvlong count;
	if(all)
		count = symtab->count;
	else{
		count = 0;
		for(uvlong i = 0; i < symtab->count; i++)
			count += symtab->symbols[i]->value != nil;
	}

	Enumeration *e = allocenum(count);
	uvlong j = 0;
	for(uvlong i = 0; i < symtab->count; i++){
		if(all || symtab->symbols[i]->value){
			e->items[j] = symtab->symbols[i];
			j++;
		}
	}
	runlock(&symtab->lock);
	return e;
}