/*
 *   Copyright 1998-2000 University of Illinois Board of Trustees
 *   Copyright 1998-2000 Mark D. Roth
 *   All rights reserved. 
 *
 *   libtar_listhash.h - header file for libtar library
 *
 *   Mark D. Roth <roth@uiuc.edu>
 *   Computing and Communications Services Office
 *   University of Illinois at Urbana-Champaign
 */


/***** list.c **********************************************************/

struct libtar_node {
  void *data;
  struct libtar_node *next;
  struct libtar_node *prev;
};
typedef struct libtar_node libtar_node_t;

struct libtar_list {
  libtar_node_t *first;
  libtar_node_t *last;
  int (*cmpfunc)();	/* called as (*cmpfunc)(void *data1, void *data2)
			   returns less than, equal to, or greater than 0
			   if data1 is <, =, or > data2 */
  int flags;
};
typedef struct libtar_list libtar_list_t;

/* values for flags */
#define LIST_USERFUNC	0	/* use cmpfunc() to order */
#define LIST_STACK	1	/* new elements go in front */
#define LIST_QUEUE	2	/* new elements go at the end */


/* creates a new, empty list */
libtar_list_t *libtar_list_new(int flags, int (*cmpfunc)());

/* remove and free() the entire list */
void libtar_list_free(libtar_list_t *l, void (*freefunc)());

/* add elements */
int libtar_list_add(libtar_list_t *l, void *data);

/* removes an element from the list - returns -1 on error */
void libtar_list_del(libtar_list_t *l, libtar_node_t **n);

/* returns 1 when valid data is returned, or 0 at end of list */
int libtar_list_next(libtar_list_t *l, libtar_node_t **n);

/* returns 1 when valid data is returned, or 0 at end of list */
int libtar_list_prev(libtar_list_t *l, libtar_node_t **n);

/* copies an existing list */
libtar_list_t *libtar_list_dup(libtar_list_t *l);

/* merges list2 and list1 and returns merged list */
libtar_list_t *libtar_list_merge(int (*cmpfunc)(), int flags,
                                   libtar_list_t *list1,
                                   libtar_list_t *list2);

/* return 1 if the data matches a list entry, 0 otherwise */
int libtar_list_search(libtar_list_t *l, libtar_node_t **n,
                        void *data, int (*matchfunc)());

/* adds elements from a string delimited by delim */
int libtar_list_add_str(libtar_list_t *l, char *str, char *delim);

/* string matching function */
int libtar_str_match(char *check, char *data);


/***** hash.c **********************************************************/

typedef struct {
  int bucket;
  libtar_node_t *node;
} libtar_hashptr_t;

typedef struct {
  int numbuckets;
  libtar_list_t **table;
  int (*hashfunc)();
} libtar_hash_t;

/* default hash function, optimized for 7-bit strings */
int libtar_str_hashfunc(char *key, int numbuckets);

/* create a new hash */
libtar_hash_t *libtar_hash_new(int num, int (*hashfunc)());

/* delete all the libtar_nodes of the hash and clean up */
void libtar_hash_free(libtar_hash_t *h, void (*freefunc)());

/* returns 1 when valid data is returned, or 0 at end of list */
int libtar_hash_next(libtar_hash_t *h, libtar_hashptr_t *hp);

/* return 1 if the data matches a list entry, 0 otherwise */
int libtar_hash_search(libtar_hash_t *h, libtar_hashptr_t *hp,
                        void *data, int (*matchfunc)());

/* return 1 if the key matches a list entry, 0 otherwise */
int libtar_hash_getkey(libtar_hash_t *h, libtar_hashptr_t *hp,
                        void *key, int (*matchfunc)());

/* inserting data */
int libtar_hash_add(libtar_hash_t *h, void *data);

/* delete an entry */
int libtar_hash_del(libtar_hash_t *h, libtar_hashptr_t *hp);


