/* Copyright 1989, 1990 by James Aspnes, David Applegate, and Bennet Yee */ /* See the file COPYING for distribution information */ #include <ctype.h> #include "db.h" #include "globals.h" extern set get_contents(datum); datum lookup(datum obj, datum var) { struct object *o; datum value; /* handle special cases */ if(var < FIXED_STRINGS) { if((o = object(obj)) == 0) { return NOTHING; } else if(isflagname(var)) { return flag_set(obj, name2flag(var)); } else switch(var) { case OWNER_NAME: return o->owner; case PARENT_NAME: return o->parent; default: /* fall through, not special */ break; } } while((o = object(obj)) != 0) { if(assoc(o->vars, var, &value)) return value; else obj = o->parent; } return NOTHING; } datum set_variable(datum obj, datum var, datum value) { struct object *o; datum flag; set loc_contents; if(!controls(me, obj) || (o = object(obj)) == 0) return 0; /* handle special cases */ if(var < FIXED_STRINGS) { if(isflagname(var)) { flag = name2flag(var); switch(flag) { case F_ADMIN: return 0; /* can't change admin status */ case F_WIZARD: case F_CONNECTED: if(!flag_set(me, F_ADMIN)) return 0; break; case F_PLAYER: case F_BUILDER: case F_PROGRAMMER: if(!flag_set(me, F_WIZARD)) return 0; break; default: break; } /* permission ok, do it */ if(value) { o->flags |= flag; } else { o->flags &= ~flag; } return 1; } else switch(var) { case OWNER_NAME: if(!flag_set(me, F_WIZARD)) { return 0; } else { o->owner = value; return 1; } break; case PARENT_NAME: if(is_ancestor(value, obj)) { /* we'd create a loop */ return 0; } else { o->parent = value; return 1; } break; case ALIASES_NAME: /* nuke the name list on our location's contents */ /* other lists will just have to lose until the next GC pass */ if((loc_contents = get_contents(o->location)) != 0) { set_clear_name_list(loc_contents); } /* fall through to normal variable set */ break; default: /* nothing special, fall through */ break; } } gc_mark_string(var); /* for incremental gc */ o->vars = set_assoc(o->vars, var, value); return 1; } datum unset(datum obj, datum var) { struct object *o; if(var < FIXED_STRINGS) { /* let set_variable deal with it */ return set_variable(obj, var, NOTHING); } else if(!controls(me, obj) || (o = object(obj)) == 0) { return 0; /* no such object as far as I'm concerned */ } else { /* it's real, nuke it */ o->vars = del_assocs(o->vars, var); return 1; } } datum lookup_action(datum obj, datum verb) { struct object *o; datum value; while((o = object(obj)) != 0) { if(assoc(o->actions, verb, &value)) return value; else obj = o->parent; } return NOTHING; } datum set_string(datum obj, datum var, datum value) { gc_mark_string(value); return set_variable(obj, var, value); } datum set_action(datum obj, datum verb, datum value) { struct object *o; if(controls(me, obj) && (o = object(obj)) != 0) { gc_mark_string(verb); gc_mark_string(value); o->actions = set_assoc(o->actions, verb, value); return 1; } else { return 0; } } datum unset_action(datum obj, datum verb) { struct object *o; if(controls(me, obj) && (o = object(obj)) != 0) { o->actions = del_assocs(o->actions, verb); return 1; } else { return 0; } } static set lookup_setvar_internal(struct object *o, datum var) { datum value; if(assoc(o->sets, var, &value)) { return ((set) value); } else { return empty_set(); } } set lookup_setvar(datum obj, datum var) { struct object *o; if((o = object(obj)) != 0) { return lookup_setvar_internal(o, var); } else { return empty_set(); } } /* no permissions checks */ datum add_to_internal(datum obj, datum var, datum value) { struct object *o; if((o = object(obj)) != 0) { o->sets = set_assoc(o->sets, var, (datum) add_member(lookup_setvar_internal(o, var), value)); gc_mark_string(var); return 1; } else { return 0; } } datum add_to(datum obj, datum var, datum value) { if(controls(me, obj) && var != CONTENTS_NAME) { return add_to_internal(obj, var, value); } else { return 0; } } /* no permissions checks */ datum take_from_internal(datum obj, datum var, datum value) { struct object *o; if((o = object(obj)) != 0) { o->sets = set_assoc(o->sets, var, (datum) del_member(lookup_setvar_internal(o, var), value)); return 1; } return 0; } datum take_from(datum obj, datum var, datum value) { if(controls(me, obj) && var != CONTENTS_NAME) { return take_from_internal(obj, var, value); } else { return 0; } } datum clear_set_var(datum obj, datum var) { datum value; struct object *o; if(controls(me, obj) && (o = object(obj)) != 0) { if(assoc(o->sets, var, &value)) { free_set((set) value); o->sets = del_assocs(o->sets, var); } return 1; } return 0; } datum contains(datum obj, datum setvar, datum thing) { return member(lookup_setvar(obj, setvar), thing); } datum count_set_var(datum obj, datum setvar) { set s; s = lookup_setvar(obj, setvar); return set_empty(s) ? 0 : set_count(s); } set get_contents(datum obj) { return lookup_setvar(obj, CONTENTS_NAME); }