/*
    slforum version 1.x - Simple chat room usable via telnet.
    Copyright (C) 1999-2001 Jeremy D. Monin, Dan Chin, Matt Lochansky
	(forum@shadowlands.org).
    Based on jdkchat version 1.3, J.D.Koftinoff Software, Ltd. (GPL'd)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*************************************************************
 *  General linked list.  Keeps track of things.
 *
 * jer 19981221.1930
 * 19990215.1830: added llist_next and llist_ldata for traversal.
 *	llist_lrmnext will be added at some point;
 *	for now, you can add things to this list
 *	but you can't remove them... this is fine,
 *	for the purpose I built it.
 ************************************************************/

#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _linkedlistlink {
  void *data;
  struct _linkedlistlink *next;
} LinkedListLink;

/** Within llist_free, this is called at each node
 *  with non-NULL data, to free that data.  (Set
 *  in llist_new)
 */
typedef void (ListData_freeFunc) (void *);

typedef struct _linkedlist {
  LinkedListLink *tail;
  ListData_freeFunc *free_data;
  int n_items;
} LinkedList;

/* compare all of these against NULL or -1 for error-checking. */

LinkedList *llist_new (ListData_freeFunc *free_data_func);  /* freefunc can be NULL */
int llist_add_start (LinkedList *L, void *data); /* -1 for error, 0 for success */
int llist_add_end (LinkedList *L, void *data);   /* -1 for error, 0 for success */
int llist_add_after (LinkedList *L, LinkedListLink *LL, void *data);

int llist_length (LinkedList *L);
void *llist_remove_start(LinkedList *L);	/* rets * to data just removed */
void* llist_remove_after(LinkedList *L, LinkedListLink *LLprev);
void llist_free (LinkedList *L);

LinkedListLink *llist_head (LinkedList *L);
LinkedListLink *llist_next (LinkedList *L, LinkedListLink *LL); /* rets NULL for no next */
void *llist_ldata (LinkedListLink *LL);


#ifdef __cplusplus
 }
#endif

#endif /* ifdef _LINKEDLIST_H_ */
