btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
btmux/tree/.svn/
/*
 * 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);
}