/* #define TEST */

/* lists with int and char* keys routines */

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

#include "config.h"

ilist_t *ilist_init(void)
{
  ilist_t *lst;

  lst = xmalloc(sizeof(ilist_t));
  ilist_next(lst) = NULL;
  ilist_prev(lst) = NULL;
  ilist_entry(lst) = NULL;	/* HEAD ID */
  ilist_key(lst) = -1;
  ilist_head_max(lst) = 0;

  return lst;
}
list_t *list_init(void)
{
  list_t *lst;

  lst = xmalloc(sizeof(list_t));
  list_next(lst) = NULL;
  list_prev(lst) = NULL;
  list_entry(lst) = NULL;	/* HEAD ID */
  list_key(lst) = NULL;
  list_head_max(lst) = 0;

  return lst;
}
int ilist_add(ilist_t * list, int key, void *entry)
/* add or replace entry by key */
{
  ilist_t *lnew, *tmp;

  if ((tmp = ilist_find(list, key)) != NULL)
    ilist_unlink(tmp);
	else
		ilist_head_max(list)++;

  lnew = xmalloc(sizeof(ilist_t));
/*printf("%p,",lnew);*/

  ilist_next(lnew) = ilist_next(list);
  ilist_prev(lnew) = list;
  if (ilist_next(lnew))
    ilist_prev(ilist_next(lnew)) = lnew;
  ilist_next(list) = lnew;
  ilist_entry(lnew) = entry;
  ilist_key(lnew) = key;

  return 0;
}
int list_add(list_t * list, char *key, void *entry)
/* add or replace entry by key */
{
  list_t *lnew, *tmp;

  if ((tmp = list_find(list, key)) != NULL)
    list_unlink(tmp);
  else
    list_head_max(list)++;

  lnew = xmalloc(sizeof(list_t));
/*printf("%p,",lnew);*/

  list_next(lnew) = list_next(list);
  list_prev(lnew) = list;
  if (list_next(lnew))
    list_prev(list_next(lnew)) = lnew;
  list_next(list) = lnew;
  list_entry(lnew) = entry;
  list_key(lnew) = xmalloc(strlen(key) + 1);
/*printf("%p\n",list_key(lnew));*/
  strcpy(list_key(lnew), key);

  return 0;
}
void ilist_unlink(ilist_t * ent)
{
  if (!ilist_prev(ent))
    return;

  ilist_next(ilist_prev(ent)) = ilist_next(ent);
  if (ilist_next(ent))
    ilist_prev(ilist_next(ent)) = ilist_prev(ent);
}
void list_unlink(list_t * ent)
{
  if (!list_prev(ent))
    return;

  list_next(list_prev(ent)) = list_next(ent);
  if (list_next(ent))
    list_prev(list_next(ent)) = list_prev(ent);

  xfree(list_key(ent));
}
int ilist_remove(ilist_t * list, int key)
{
  ilist_t *lcur;

  if (ilist_prev(list))
    return -1;

  lcur = ilist_find(list, key);
  if (lcur)
  {
    ilist_head_max(list)--;
    ilist_unlink(lcur);
    return 0;
  }

  return -1;			/* not found */
}
int list_remove(list_t * list, char *key)
{
  list_t *lcur;

  if (list_prev(list))
    return -1;

  lcur = list_find(list, key);
  if (lcur)
  {
    list_head_max(list)--;
    list_unlink(lcur);
    return 0;
  }

  return -1;			/* not found */
}
void ilist_free(ilist_t * list)
{
  ilist_t *cur, *tmp;

	if(ilist_head_max(list)!=0)
   for (cur = ilist_next(list);;)
   {
/*printf("%p\n",cur);*/
    tmp = cur;
    cur = ilist_next(cur);
    xfree(tmp);
    if (cur == NULL)
      break;
   }
  xfree(list);
}
void list_free(list_t * list)
{
  list_t *cur, *tmp;

  if(list_head_max(list)!=0)
   for (cur = list_next(list);;)
   {
/*printf("%p\n",cur);*/
    xfree(list_key(cur));
    tmp = cur;
    cur = list_next(cur);
    xfree(tmp);
    if (cur == NULL)
      break;
   }
  xfree(list);
}
ilist_t *ilist_find(ilist_t * list, int key)
{
  register ilist_t *cur;

  for (cur = ilist_next(list); cur; cur = ilist_next(cur))
    if (ilist_key(cur) == key)
      return cur;
  return NULL;
}
void *ilist_find_entry(ilist_t *ilist,int key)
{
  ilist_t *itmp; char *ctmp;
  itmp=ilist_find(ilist,key);
  if(itmp==NULL) return NULL;
  ctmp=ilist_entry(itmp);
  if(ctmp==NULL) return NULL;
  return ctmp;
}
list_t *list_find(list_t * list, char *key)
{
  register list_t *cur;

  for (cur = list_next(list); cur; cur = list_next(cur))
    if (!strcasecmp(list_key(cur), key))
      return cur;
  return NULL;
}
void *list_find_entry(list_t *list,char *key)
{
  list_t *ltmp; char *ctmp;
  ltmp=list_find(list,key);
  if(ltmp==NULL) return NULL;
  ctmp=list_entry(ltmp);
  if(ctmp==NULL) return NULL;
  return ctmp;
}
void *list_find_key(list_t *list,char *key)
{
  list_t *ltmp; char *ctmp;
  ltmp=list_find(list,key);
  if(ltmp==NULL) return NULL;
  ctmp=list_key(ltmp);
  if(ctmp==NULL) return NULL;
  return ctmp;
}
list_t *list_get(list_t *list,int n)
{
  list_t *cur; int i;

  if(n>=list_head_max(list)) return NULL;

  for (cur = list_next(list),i=0;i!=list_head_max(list)-n-1;i++)
  {
/*printf("%p\n",cur);*/
    cur = list_next(cur);
    if (cur == NULL)
      return NULL;
  }
  return cur;
}
ilist_t *ilist_get(ilist_t *list,int n)
{
  ilist_t *cur; int i;

  if(n>=ilist_head_max(list)) return NULL;

  for (cur = ilist_next(list),i=0;i!=ilist_head_max(list)-n-1;i++)
  {
/*printf("%p\n",cur);*/
    cur = ilist_next(cur);
    if (cur == NULL)
      return NULL;
  }
  return cur;
}
void *list_get_entry(list_t *list,int n)
{
  list_t *ltmp; char *ctmp;
  ltmp=list_get(list,n);
  if(ltmp==NULL) return NULL;
  ctmp=list_entry(ltmp);
  if(ctmp==NULL) return NULL;
  return ctmp;
}
void *ilist_get_entry(ilist_t *list,int n)
{
  ilist_t *ltmp; char *ctmp;
  ltmp=ilist_get(list,n);
  if(ltmp==NULL) return NULL;
  ctmp=ilist_entry(ltmp);
  if(ctmp==NULL) return NULL;
  return ctmp;
}
void *list_get_key(list_t *list,int n)
{
  list_t *ltmp; char *ctmp;
  ltmp=list_get(list,n);
  if(ltmp==NULL) return NULL;
  ctmp=list_key(ltmp);
  if(ctmp==NULL) return NULL;
  return ctmp;
}
#ifdef TEST
main(int argc, char *argv[])
{
  char buff[9999];
  char *p;
  FILE *fp;
  list_t *list, *res;
  int i = 1;

  fp = fopen(argv[1], "r");
  if (!fp)
  {
    perror("");
    abort2();
  }
  list = list_init();
  while (1)
  {
    if (!fgets(buff, 9999, fp))
      break;
    p = malloc(strlen(buff) + 1);
    strcpy(p, buff);
    sprintf(buff, "%d", i++);
    list_add(list, buff, p);
  }
  printf("max=%d\n",list_head_max(list));
  printf("enter n: ");
  scanf("%s", buff);
  res = list_get(list, atoi(buff));
  printf("res=%p\n", res);
  printf("entry=%s\n", list_entry(res));
  list_free(list);
}
#endif


syntax highlighted by Code2HTML, v. 0.9.1