/* -------------------------------------------------------------------- */
/* SMS Client, send messages to mobile phones and pagers		*/
/*									*/
/* gs_list.c								*/
/*									*/
/*  Copyright (C) 1997,1998 Angelo Masci				*/
/*									*/
/*  This library is free software; you can redistribute it and/or	*/
/*  modify it under the terms of the GNU Library General Public		*/
/*  License as published by the Free Software Foundation; either	*/
/*  version 2 of the License, or (at your option) any later version.	*/
/*									*/
/*  This library is distributed in the hope that it will be useful,	*/
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of	*/
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU	*/
/*  Library General Public License for more details.			*/
/*									*/
/*  You should have received a copy of the GNU Library General Public	*/
/*  License along with this library; if not, write to the Free		*/
/*  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.	*/
/*									*/
/*  You can contact the author at this e-mail address:			*/
/*									*/
/*  angelo@styx.demon.co.uk						*/
/*									*/
/* -------------------------------------------------------------------- */
/* $Id$
   -------------------------------------------------------------------- */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/common.h"
#include "logfile/logfile.h"
#include "gs_token.h"
#include "error.h"

/* -------------------------------------------------------------------- */

static TOKEN *malloc_token(void);
static TOKEN_LIST *malloc_token_list_item(void);
static TOKEN *update_token(TOKEN *token, char *str, int type, int ptr_type, void *ptr);

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
static TOKEN *malloc_token(void)
{
	TOKEN *token;

	token = (TOKEN *)malloc(sizeof(TOKEN));
	if (token == NULL)
	{
		lprintf(LOG_ERROR, "malloc() failed\n");
		return NULL;
	}

	return token;
}


/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
static TOKEN_LIST *malloc_token_list_item(void)
{
	TOKEN_LIST
		*list_item;


	list_item = (TOKEN_LIST *)malloc(sizeof(TOKEN_LIST));
	if (list_item == NULL)
	{
		lprintf(LOG_ERROR, "malloc() failed\n");
		return NULL;
	}

	list_item->token = malloc_token();
	if (list_item->token == NULL)
	{
		lprintf(LOG_ERROR, "malloc() failed\n");

		free(list_item);
		return NULL;
	}

	list_item->next  = NULL;

	return list_item;
}


/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
static TOKEN *update_token(TOKEN *token, char *str, int type, int ptr_type, void *ptr)
{
	token->str = strdup(str);
	if (token->str == NULL)
	{
		lprintf(LOG_ERROR, "strdup() failed\n");
		return NULL;
	}

	token->type     = type;
	token->ptr_type = ptr_type;
	token->ptr      = ptr;

	lprintf(LOG_VERYVERBOSE, "Updating %s, %d, %d, %p\n", str, type, ptr_type, ptr);

	return token;
}


/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
TOKEN *gs_new_token(char *str, int type, int ptr_type, void *ptr)
{
	TOKEN *token;

	token = malloc_token();
	if (token == NULL)
	{	return NULL;
	}

	return update_token(token, str, type, ptr_type, ptr);
}


/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
TOKEN *gs_find_item(TOKEN_LIST *list, char *str, int type)
{
	TOKEN_LIST
		*item;


	item = list;
	while(item != NULL)
	{
		if ((strcmp(item->token->str, str) == 0) &&
		    (item->token->type == type))
		{	return item->token;
		}

		item = item->next;
	}

	return NULL;
}

/* -------------------------------------------------------------------- */
/* Try to locate item if it already exists, update			*/
/* it and return list.							*/
/* If the item cannot be located, create a new item,			*/
/* insert at the start of the list and return the new list.		*/
/* If list is empty add item to list and return list			*/
/* -------------------------------------------------------------------- */
TOKEN_LIST *gs_add_token_list_item(TOKEN_LIST *list, TOKEN **token, char *str, int type, int ptr_type, void *ptr)
{
	TOKEN_LIST
		*list_item;
	TOKEN	*item;


	lprintf(LOG_VERYVERBOSE, "Adding token '%s'\n", str);

	item = gs_find_item(list, str, type);
	if (item != NULL)
	{
		lprintf(LOG_VERYVERBOSE, "Found token '%s'\n", str);

		if (update_token(item, str, type, ptr_type, ptr) == NULL)
		{	return NULL;
		}

		*token = item;
		return list;
	}

	lprintf(LOG_VERYVERBOSE, "Creating token '%s'\n", str);

	list_item = malloc_token_list_item();
	if (list_item == NULL)
	{	return NULL;
	}


	list_item->next = list;

	if (update_token(list_item->token, str, type, ptr_type, ptr) == NULL)
	{	return NULL;
	}

	*token = list_item->token;
	return list_item;
}
