ref: ad872eeb19b4fcc41a5d34750ca6cdcf88a39795
dir: /symtab.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include "dat.h"
#include "fns.h"
struct {
char *name;
void *(*init)(void);
} defaultsyms[] = {
{ "⎕IO", init_quadio },
};
Symtab *
allocsymtab(int defaults)
{
Symtab *s = alloc(DataSymtab);
if(defaults){
for(uvlong i = 0; i < nelem(defaultsyms); i++){
uvlong symb = sym(s, defaultsyms[i].name);
symset(s, symb, defaultsyms[i].init());
}
}
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;
}
Qid
symqid(Symtab *s, uvlong id)
{
Qid qid;
rlock(&s->lock);
qid = s->symbols[id]->qsymbol;
runlock(&s->lock);
return qid;
}
void
symset(Symtab *s, uvlong id, void *newval)
{
wlock(&s->lock);
s->symbols[id]->value = newval;
wunlock(&s->lock);
}
Enumeration *
enumsymbols(Symtab *symtab)
{
rlock(&symtab->lock);
Enumeration *e = allocenum(symtab->count);
for(uvlong i = 0; i < symtab->count; i++)
e->items[i] = symtab->symbols[i];
runlock(&symtab->lock);
return e;
}