/* 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" #include "externs.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; } case PARENT_NAME: if (is_ancestor (value, obj)) { /* we'd create a loop */ return 0; } else { o->parent = value; return 1; } 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); }