/* * vattr.c -- Manages the user-defined attributes. */ /* * $Id: vattr.c,v 1.4 2005/08/08 09:43:07 murrayma Exp $ */ #include "copyright.h" #include "config.h" #include "copyright.h" #include "mudconf.h" #include "vattr.h" #include "alloc.h" #include "htab.h" #include "externs.h" #include "rbtree.h" static void fixcase(char *); static char *store_string(char *); /* * Allocate space for strings in lumps this big. */ #define STRINGBLOCK 1000 /* * Current block we're putting stuff in */ static char *stringblock = (char *) 0; /* * High water mark. */ static int stringblock_hwm = 0; static rbtree *vt; static int vattr_compare(void *vleft, void *vright, void *arg) { char *left = (char *)vleft; char *right = (char *)vright; return strcmp(left, right); } void vattr_init(void) { vt = rb_init(vattr_compare, NULL); #if 0 hashinit(&mudstate.vattr_name_htab, 256 * HASH_FACTOR); #endif } VATTR *vattr_find(name) char *name; { register VATTR *vp; if (!ok_attr_name(name)) return (NULL); #if 0 vp = (VATTR *) hashfind(name, &mudstate.vattr_name_htab); #endif vp = (VATTR *) rb_find(vt, (void *)name); /* * vp is NULL or the right thing. It's right, either way. */ return (vp); } VATTR *vattr_alloc(name, flags) char *name; int flags; { int number; if (((number = mudstate.attr_next++) & 0x7f) == 0) number = mudstate.attr_next++; anum_extend(number); return (vattr_define(name, number, flags)); } VATTR *vattr_define(name, number, flags) char *name; int number, flags; { VATTR *vp; /* * Be ruthless. */ if (strlen(name) > VNAME_SIZE) name[VNAME_SIZE - 1] = '\0'; fixcase(name); if (!ok_attr_name(name)) return (NULL); if ((vp = vattr_find(name)) != NULL) return (vp); vp = (VATTR *) malloc(sizeof(VATTR)); vp->name = store_string(name); vp->flags = flags; vp->number = number; #if 0 hashadd(vp->name, (int *) vp, &mudstate.vattr_name_htab); #endif rb_insert(vt, (void *)vp->name, (void *)vp); anum_extend(vp->number); anum_set(vp->number, (ATTR *) vp); return (vp); } void do_dbclean(player, cause, key) dbref player, cause; int key; { VATTR *vp; dbref i; int notfree; for(vp = (VATTR *) rb_search(vt, SEARCH_FIRST, NULL); vp != NULL; vp = (VATTR *) rb_search(vt, SEARCH_GT, vp)) { #if 0 for (vp = (VATTR *) hash_firstentry(&mudstate.vattr_name_htab); vp != NULL; vp = (VATTR *) hash_nextentry(&mudstate.vattr_name_htab)) { #endif notfree = 0; DO_WHOLE_DB(i) { if (atr_get_raw(i, vp->number) != NULL) { notfree = 1; break; } } if (!notfree) { anum_set(vp->number, NULL); #if 0 hashdelete(vp->name, &mudstate.vattr_name_htab); #endif rb_delete(vt, vp->name); free((char *) vp); } } #ifndef STANDALONE notify(player, "Database cleared of stale attribute entries."); #endif } void vattr_delete(name) char *name; { VATTR *vp; int number; fixcase(name); if (!ok_attr_name(name)) return; number = 0; #if 0 vp = (VATTR *) hashfind(name, &mudstate.vattr_name_htab); #endif vp = (VATTR *) rb_find(vt, name); if (vp) { number = vp->number; anum_set(number, NULL); #if 0 hashdelete(name, &mudstate.vattr_name_htab); #endif rb_delete(vt, name); free((char *) vp); } return; } VATTR *vattr_rename(name, newname) char *name, *newname; { VATTR *vp; fixcase(name); if (!ok_attr_name(name)) return (NULL); /* * Be ruthless. */ if (strlen(newname) > VNAME_SIZE) newname[VNAME_SIZE - 1] = '\0'; fixcase(newname); if (!ok_attr_name(newname)) return (NULL); #if 0 vp = (VATTR *) hashfind(name, &mudstate.vattr_name_htab); #endif vp = (VATTR *) rb_find(vt, name); if (vp) vp->name = store_string(newname); return (vp); } VATTR *vattr_first(void) { #if 0 return (VATTR *) hash_firstentry(&mudstate.vattr_name_htab); #endif return (VATTR *) rb_search(vt, SEARCH_FIRST, NULL); } VATTR *vattr_next(vp) VATTR *vp; { if (vp == NULL) return (vattr_first()); #if 0 return ((VATTR *) hash_nextentry(&mudstate.vattr_name_htab)); #endif return ((VATTR *) rb_search(vt, SEARCH_GT, vp)); } static void fixcase(name) char *name; { char *cp = name; while (*cp) { *cp = ToUpper(*cp); cp++; } return; } /* * Some goop for efficiently storing strings we expect to * keep forever. There is no freeing mechanism. */ static char *store_string(str) char *str; { int len; char *ret; len = strlen(str); /* * If we have no block, or there's not enough room left in the * * * * current one, get a new one. */ if (!stringblock || (STRINGBLOCK - stringblock_hwm) < (len + 1)) { stringblock = (char *) malloc(STRINGBLOCK); if (!stringblock) return ((char *) 0); stringblock_hwm = 0; } ret = stringblock + stringblock_hwm; StringCopy(ret, str); stringblock_hwm += (len + 1); return (ret); }