/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 *
 * http://www.sgi.com
 *
 * For further information regarding this notice, see:
 *
 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
 *
 */
/* $Id: symbol.c,v 1.4 2002/05/28 16:26:16 robbiew Exp $ */
/*
 *			Generic Symbol Table
 *
 * This is intended to look a lot like ndbm, except that all information
 * is kept in memory, and a multi-key, hierarchical access mode is provided.
 * This is largely patterned after the Berkeley "DB" package.
 *
 *			    Requirements
 *
 *	- "key" is ASCII (a C string, in fact)
 *
 *			Symbol Table Structure
 *
 *	Two data structures:
 *		Symbol Table Header
 *		Symbol Table Node
 *
 *	A symbol table header consists of a magic number, a pointer to
 *	the first node in the symbol table, and a cursor that is used
 *	when sequentialy stepping thru the entire list.
 *
 *	Symbol table nodes contain a pointer to a key, a pointer to this
 *	key's data, and a pointer to the next node in the chain.
 *	Note that to create a hierarchical symbol table, a node is created
 *	whose data points to a symbol table header.
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "symbol.h"
#include "splitstr.h"

#define SYM_MAGIC	0xbadc0de

/*
 * Some functions can report an error message by assigning it to this
 * string.
 */

static char *sym_error = NULL;

/*
 *	Memory Allocators
 *
 * newsym() allocates a new symbol table header node
 * mknode(...) allocates a new symbol table entry
 */

SYM newsym()
{
	SYM h;

	if ((h = (SYM) malloc(sizeof(struct symh))) == NULL) {
		sym_error = "sym header malloc failed!";
		return (NULL);
	}

	h->magic = SYM_MAGIC;
	h->sym = NULL;
	h->cursor = NULL;
	return (h);
}

static struct sym *mknode(struct sym *next, char *key, void *data)
{
	struct sym *n;

	if ((n = (struct sym *)malloc(sizeof(struct sym))) == NULL) {
		sym_error = "sym node malloc failed!";
		return (NULL);
	}

	n->next = next;
	n->key = strdup(key);
	n->data = data;

	if (n->key == NULL) {
		sym_error = "sym node strdup(key) failed!";
		return (NULL);
	}
	return (n);
}

/*
 * Search for a key in a single-level symbol table hierarchy.
 */
static struct sym *find_key1(struct sym *sym, char *key)
{
	while (sym != NULL)
		if (strcmp(sym->key, key) == 0)
			return (sym);
		else
			sym = sym->next;
	return (NULL);
}

/*
 * Create a new key node, add it to the *end* of this list
 */
static int add_key(SYM sym, char *key, void *data)
{
	register struct sym *sn;

	if (sym->sym == NULL) {
		sym->sym = mknode(NULL, key, data);
		if (sym->sym == NULL) {
			return (-1);
		}
	} else {
		for (sn = sym->sym; sn != NULL && sn->next != NULL;
		     sn = sn->next) ;
		sn->next = mknode(NULL, key, data);
		assert(sn->next != NULL);
		if (sn->next == NULL)
			return (-1);
	}
	return (0);
}

/*
 *  Create a new symbol table
 */
SYM sym_open(int flags, int mode, int openinfo)
{
	return (newsym());
}

/*
 *	Add (key, data) to an existing symbol table
 *
 *  If the key does not exist, a new key is added to the end of the list.
 *  If the key exists and the PUT_REPLACE flag is not supplied, return EEXIST.
 *  If a symbol table entry in a multi-part key is not a symbol table (i.e.
 *  element two of a three or more element key), return ENOTDIR.
 *
 *  "data" is not duplicated and must not point to a static area that could
 *  go away before the element is deleted (such as a local string in a
 *  function)
 *
 *  "key" is duplicated as needed, and is not modified.
 *
 * Code:
 * chop up key on commas
 *
 * search until a key element isn't found in the key tree, the key list is
 * exhausted, or a key's data element is not a sub-tree
 *
 * if the key list is exhausted, return a "duplicate entry" error
 *
 * if the last found key's data element is not a sub-tree, return
 * something like "ENOTDIR".
 *
 * add new keys for sub-trees until key list is exhausted;
 * last node gets 'data'.
 *
 */
int sym_put(SYM sym, char *key, void *data, int flags)
{
	const char **keys;	/* key split into a 2d string array */
	char **kk;
	char *nkey;		/* copy of 'key' -- before split */
	SYM csym, ncsym;	/* search: current symbol table */
	struct sym *nsym = NULL;	/* search: found symbol entry */

	if (sym == NULL)
		return (EINVAL);

	nkey = strdup(key);
	keys = splitstr(key, ",", NULL);

	if (keys == NULL)
		return (EINVAL);

	for (kk = (char **)keys, csym = sym;
	     *kk != NULL && (nsym = find_key1(csym->sym, *kk)) != NULL;
	     csym = nsym->data) {

		if (*++kk == NULL)
			break;

		if (nsym->data == NULL) {	/* fatal error */
			free(nkey);
			splitstr_free(keys);
			return (ENOTDIR);
		}
		if (((SYM) (nsym->data))->magic != SYM_MAGIC) {
			free(nkey);
			splitstr_free(keys);
			return (ENOTDIR);
		}
	}

	if (*kk == NULL) {	/* found a complete match */
		free(nkey);
		splitstr_free(keys);

		if (flags == PUT_REPLACE) {
			nsym->data = data;
			return (0);
		} else {
			return (EEXIST);
		}
	}

	/* csym is a ptr to a list */
	for (; *kk != NULL; kk++) {
		if (*(kk + 1) != NULL) {
			add_key(csym, *kk, (void *)(ncsym = newsym()));
			csym = ncsym;
		} else {
			add_key(csym, *kk, data);	/* last key */
		}
	}

	free(nkey);
	splitstr_free(keys);
	return (0);
}

/*
 *	Retrieve a Symbol's Contents
 *
 *  "key" is not modified.
 *  If the key cannot be found, NULL is returned
 */
void *sym_get(SYM sym, char *key)
{
	char *nkey;
	const char **keys;	/* key split into a 2d string array */
	char **kk;
	SYM csym;		/* search: current symbol table */
	struct sym *nsym = NULL;	/* search: found symbol entry */

	if (sym == NULL)
		return (NULL);

	nkey = strdup(key);
	keys = splitstr(nkey, ",", NULL);
	if (keys == NULL)
		return (NULL);

	for (kk = (char **)keys, csym = sym;
	     *kk != NULL && (nsym = find_key1(csym->sym, *kk)) != NULL;
	     csym = nsym->data) {

		if (*++kk == NULL)
			break;

		if (nsym->data == NULL) {	/* fatal error */
			free(nkey);
			splitstr_free(keys);
			return (NULL);
		}
		if (((SYM) (nsym->data))->magic != SYM_MAGIC) {
			free(nkey);
			splitstr_free(keys);
			return (NULL);
		}
	}

	if (*kk == NULL) {	/* found a complete match */
		splitstr_free(keys);
		free(nkey);
		return (nsym->data);
	} else {
		splitstr_free(keys);
		free(nkey);
		return (NULL);
	}
}

/*
 *  Step thru a symbol table list
 *
 *  The cursor must be set by R_CURSOR, R_FIRST before using R_NEXT.
 *  NULL is returned when no more items are available.
 */
int sym_seq(SYM sym, DBT * key, DBT * data, int flags)
{
	SYM csym;

	switch (flags) {
		/*
		 * A number of ways to do this:
		 * specificly: sym_seq( .., "key,key") sets to Nth element of the 2nd
		 *  level symbol table
		 * sym_seq(.., "key,key,") sets to the first element of the 3rd
		 *  level symbol table
		 *
		 * sym_seq(.., "key,key") where both must be complete keys, sets
		 *  cursor to the first element of the 3rd level symbol table;
		 *  if there is no 3rd level, return an error.
		 */
	case R_CURSOR:
		csym = (SYM) sym_get(sym, (char *)key->data);
		if (csym == NULL || csym->magic != SYM_MAGIC) {
			return (2);
		}
		sym->cursor = csym->sym;
		if (sym->cursor == NULL)
			return (1);
		key->data = sym->cursor->key;
		data->data = sym->cursor->data;

		return (0);

	case R_FIRST:
		sym->cursor = sym->sym;
		if (sym->cursor == NULL)
			return (1);
		key->data = sym->cursor->key;
		data->data = sym->cursor->data;

		return (0);

	case R_NEXT:
		if (sym->cursor == NULL)
			return (1);
		sym->cursor = sym->cursor->next;

		if (sym->cursor == NULL)
			return (1);

		key->data = sym->cursor->key;
		data->data = sym->cursor->data;

		return (0);

	case R_LAST:
	case R_PREV:
	default:
		return (-1);
	}
}

/*
 *	Dump a symbol table's keys.
 *	Handles hierarchies, using a double quote to indicate depth, one
 *	double quote for each level.
 */
int sym_dump(SYM sym, int depth)
{

	register struct sym *se;	/* symbol entry */
	register int d;

	if (sym == NULL || sym->magic != SYM_MAGIC)
		return -1;

	for (se = sym->sym; se != NULL; se = se->next) {
		for (d = 0; d < depth; d++) {
			putchar('"');
			putchar(' ');
		}
		printf("%s\n", se->key);
		sym_dump((SYM) se->data, depth + 1);
	}
	return 0;
}

/*
 * sym dump, but data is _always_ a string (print it)
 */
int sym_dump_s(SYM sym, int depth)
{

	register struct sym *se;	/* symbol entry */
	register int d;

	if (sym == NULL)
		return 0;

	if (sym->magic != SYM_MAGIC) {
		for (d = 0; d < depth; d++) {
			putchar('"');
			putchar(' ');
		}
		printf(" = %s\n", (char *)sym);
		return 0;
	}

	for (se = sym->sym; se != NULL; se = se->next) {
		for (d = 0; d < depth; d++) {
			putchar('"');
			putchar(' ');
		}
		printf("%s", se->key);
		if (((SYM) se->data)->magic == SYM_MAGIC) {
			putchar('\n');
			sym_dump_s((SYM) se->data, depth + 1);
		} else {
			printf("(%p) = %s (%p)\n", se->key, (char *)se->data,
			       se->data);
		}
	}
	return 0;
}

/*
 *	Remove an entire symbol table (done bottom up)
 */
int sym_rm(SYM sym, int flags)
{
	register struct sym *se, *nse;	/* symbol entry */

	if (sym == NULL)
		return 0;

	if (sym->magic != SYM_MAGIC) {
		if (!(flags & RM_DATA))
			free(sym);
		return 0;
	}

	for (se = sym->sym; se != NULL;) {
		sym_rm((SYM) se->data, flags);
		nse = se->next;
		if (flags & RM_KEY)
			free(se->key);
		if (flags & RM_DATA)
			free(se->data);
		free(se);
		se = nse;
	}
	if (!(flags & RM_DATA))
		free(sym);
	return 0;
}
