fbmuck-6.05/auto/
fbmuck-6.05/contrib/jresolver/
fbmuck-6.05/contrib/jresolver/org/
fbmuck-6.05/contrib/jresolver/org/fuzzball/
fbmuck-6.05/docs/devel/
fbmuck-6.05/game/
fbmuck-6.05/game/logs/
fbmuck-6.05/game/muf/
fbmuck-6.05/scripts/
fbmuck-6.05/src_docs/
#include "copyright.h"
#include "config.h"
#include "params.h"

#include "db.h"
#include "tune.h"
#include "props.h"
#include "externs.h"
#include "interface.h"


/* propdirs.c -- handles propdirs property creation, deletion, and finding.  */
/* WARNING: These routines all hack up the path string passed to them. */

/* USES:

     PropPtr locate_prop(PropPtr root, char *name)
       if root is NULL, return NULL.

     PropPtr new_prop(PropPtr *root, char *name)
       if *root is NULL, create a new propdir, then insert the prop

     PropPtr delete_prop(PropPtr *root, char *name)
       when last prop in dir is deleted, destroy propdir & change *root to NULL

     PropPtr first_node(PropPtr root)
       if root is NULL, return NULL

     PropPtr next_node(PropPtr root)
       if root is NULL, return NULL

 */


/*
 * returns pointer to the new property node.  Returns a pointer to an
 *   existing elem of the given name, if one already exists.  Returns
 *   NULL if the name given is bad.
 * root is the pointer to the root propdir node.  This is updated in this
 *   routine to point to the new root node of the structure.
 * path is the name of the property to insert
 */
PropPtr
propdir_new_elem(PropPtr * root, char *path)
{
	PropPtr p;
	char *n;

	while (*path && *path == PROPDIR_DELIMITER)
		path++;
	if (!*path)
		return (NULL);
	n = index(path, PROPDIR_DELIMITER);
	while (n && *n == PROPDIR_DELIMITER)
		*(n++) = '\0';
	if (n && *n) {
		/* just another propdir in the path */
		p = new_prop(root, path);
		return (propdir_new_elem(&PropDir(p), n));
	} else {
		/* aha, we are finally to the property itself. */
		p = new_prop(root, path);
		return (p);
	}
}


/* returns pointer to the updated propdir structure's root node */
/* root is the pointer to the root propdir node */
/* path is the name of the property to delete */
PropPtr
propdir_delete_elem(PropPtr root, char *path)
{
	PropPtr p;
	char *n;

	if (!root)
		return (NULL);
	while (*path && *path == PROPDIR_DELIMITER)
		path++;
	if (!*path)
		return (root);
	n = index(path, PROPDIR_DELIMITER);
	while (n && *n == PROPDIR_DELIMITER)
		*(n++) = '\0';
	if (n && *n) {
		/* just another propdir in the path */
		p = locate_prop(root, path);
		if (p && PropDir(p)) {
			/* yup, found the propdir */
			SetPDir(p, propdir_delete_elem(PropDir(p), n));
			if (!PropDir(p) && PropType(p) == PROP_DIRTYP) {
				root = delete_prop(&root, PropName(p));
			}
		}
		/* return the updated root pntr */
		return (root);
	} else {
		/* aha, we are finally to the property itself. */
		p = locate_prop(root, path);
		if (p && PropDir(p)) {
			delete_proplist(PropDir(p));
		}
		(void) delete_prop(&root, path);
		return (root);
	}
}


/* returns pointer to given property */
/* root is the pointer to the root propdir node */
/* path is the name of the property to find */
PropPtr
propdir_get_elem(PropPtr root, char *path)
{
	PropPtr p;
	char *n;

	if (!root)
		return (NULL);
	while (*path && *path == PROPDIR_DELIMITER)
		path++;
	if (!*path)
		return (NULL);
	n = index(path, PROPDIR_DELIMITER);
	while (n && *n == PROPDIR_DELIMITER)
		*(n++) = '\0';
	if (n && *n) {
		/* just another propdir in the path */
		p = locate_prop(root, path);
		if (p && PropDir(p)) {
			/* yup, found the propdir */
			return (propdir_get_elem(PropDir(p), n));
		}
		return (NULL);
	} else {
		/* aha, we are finally to the property subname itself. */
		if ((p = locate_prop(root, path))) {
			/* found the property! */
			return (p);
		}
		return (NULL);			/* nope, doesn't exist */
	}
}


/* returns pointer to first property in the given propdir */
/* root is the pointer to the root propdir node */
/* path is the name of the propdir to find the first node of */
PropPtr
propdir_first_elem(PropPtr root, char *path)
{
	PropPtr p;

	while (*path && *path == PROPDIR_DELIMITER)
		path++;
	if (!*path)
		return (first_node(root));
	p = propdir_get_elem(root, path);
	if (p && PropDir(p)) {
		return (first_node(PropDir(p)));	/* found the property! */
	}
	return (NULL);				/* nope, doesn't exist */
}


/* returns pointer to next property after the given one in the propdir */
/* root is the pointer to the root propdir node */
/* path is the name of the property to find the next node after */
/* Note: Finds the next alphabetical property, regardless of the existence
	  of the original property given. */
PropPtr
propdir_next_elem(PropPtr root, char *path)
{
	PropPtr p;
	char *n;

	if (!root)
		return (NULL);
	while (*path && *path == PROPDIR_DELIMITER)
		path++;
	if (!*path)
		return (NULL);
	n = index(path, PROPDIR_DELIMITER);
	while (n && *n == PROPDIR_DELIMITER)
		*(n++) = '\0';
	if (n && *n) {
		/* just another propdir in the path */
		p = locate_prop(root, path);
		if (p && PropDir(p)) {
			/* yup, found the propdir */
			return (propdir_next_elem(PropDir(p), n));
		}
		return (NULL);
	} else {
		/* aha, we are finally to the property subname itself. */
		return (next_node(root, path));
	}
}


/* return true if a property contains a propdir */
int
propdir_check(PropPtr root, char *path)
{
	PropPtr p;

	if ((p = propdir_get_elem(root, path)))
		return (PropDir(p) != NULL);
	return (0);
}


const char *
propdir_name(const char *name)
{
	static char pnbuf[BUFFER_LEN];
	const char *i;
	char *o;

	i = name;
	o = pnbuf;
	while (*i) {
		while (*i == PROPDIR_DELIMITER)
			i++;
		*o++ = PROPDIR_DELIMITER;
		while (*i && *i != PROPDIR_DELIMITER)
			*o++ = *i++;
	}
	*o = '\0';
	while (*o != PROPDIR_DELIMITER)
		*o-- = '\0';
	return pnbuf;
}

/* returns path of first unloaded propdir in given path */
/* returns NULL if all propdirs to path are loaded */
/* root is the pointer to the root propdir node */
/* path is the name of the propdir to find */
const char *
propdir_unloaded(PropPtr root, const char *path)
{
	PropPtr p;
	const char *n;
	char *o, *l;
	static char buf[BUFFER_LEN];

	if (!root)
		return NULL;
	n = path;
	o = buf;
	while (*n == PROPDIR_DELIMITER)
		n++;
	if (!*n)
		return NULL;
	while (*n) {
		*o++ = '/';
		l = o;
		while (*n && *n != PROPDIR_DELIMITER)
			*o++ = *n++;
		while (*n == PROPDIR_DELIMITER)
			n++;
		*o = '\0';
		p = locate_prop(root, l);
		if (!p) {
			return NULL;
		}
		if (PropFlags(p) & PROP_DIRUNLOADED) {
			SetPFlags(p, (PropFlags(p) & ~PROP_DIRUNLOADED));
			return buf + 1;
		}
		root = PropDir(p);
	}
	return NULL;
}