/*********************************************************************/
/* file: llist.c - linked-list datastructure                         */
/*                             TINTIN III                            */
/*          (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t             */
/*                     coded by peter unold 1992                     */
/*********************************************************************/
#include <string.h>
#include "tintin.h"


/***************************************/
/* init list - return: ptr to listhead */
/***************************************/
struct listnode *init_list()
{
  struct listnode *listhead;

  if((listhead=(struct listnode *)(malloc(sizeof(struct listnode))))==NULL) {
    fprintf(stderr, "couldn't alloc listhead\n");
    exit(1);
  }
  listhead->next=NULL;
  return(listhead);
}

/************************************************/
/* kill list - run throught list and free nodes */
/************************************************/ 
void kill_list(struct listnode *nptr)
{
  struct listnode *nexttodel;

  nexttodel=nptr->next;
  free(nptr);

  for(nptr=nexttodel; nptr; nptr=nexttodel) {
    nexttodel=nptr->next;
    free(nptr->left);
    free(nptr->right);
    free(nptr);
  }
}

/***********************************************/
/* make a copy of a list - return: ptr to copy */
/***********************************************/
struct listnode *copy_list(struct listnode *sourcelist)
{
  struct listnode *resultlist;

  resultlist=init_list();
  while(sourcelist=sourcelist->next)
    insertnode_list(resultlist, sourcelist->left, sourcelist->right);
  
  return(resultlist);
} 

/*****************************************************************/
/* create a node containing the ltext, rtext fields and stuff it */
/* into the list - in lexicographical order                      */
/*****************************************************************/
void insertnode_list(struct listnode *listhead, char *ltext, char *rtext)
{
  struct listnode *nptr, *nptrlast, *newnode;

  if((newnode=(struct listnode *)(malloc(sizeof(struct listnode))))==NULL) {
    fprintf(stderr, "couldn't malloc listhead");
    exit(1);
  }
  newnode->left=(char *)malloc(strlen(ltext)+1);
  newnode->right=(char *)malloc(strlen(rtext)+1);
  strcpy(newnode->left, ltext);
  strcpy(newnode->right, rtext);

  nptr=listhead;

  while((nptrlast=nptr) &&   (nptr=nptr->next)) {
    if(strcmp(ltext, nptr->left)<=0) {
      newnode->next=nptr;
      nptrlast->next=newnode;
      return;
    }
  }
  nptrlast->next=newnode;
  newnode->next=NULL;
}

/*****************************/
/* delete a node from a list */
/*****************************/
void deletenode_list(struct listnode *listhead, struct listnode *nptr)
{
  struct listnode *lastnode=listhead;

  while(listhead=listhead->next) {
    if(listhead==nptr) {
      lastnode->next=listhead->next;
      free(listhead->left);
      free(listhead->right);
      free(listhead);
      return;
    }
    lastnode=listhead;
  }
  return;
}

/********************************************************/
/* search for a node containing the ltext in left-field */
/* return: ptr to node on succes / NULL on failure      */
/********************************************************/
struct listnode *searchnode_list(struct listnode *listhead, char *cptr)
{
  int i;
  while(listhead=listhead->next) {
    if((i=strcmp(listhead->left, cptr))==0)
      return listhead;
    else if(i>0)
      return NULL;
  }
  return NULL;
}

/************************************/
/* show contens of a node on screen */
/************************************/
void shownode_list(struct listnode *nptr)
{
  printf("%s=%s\n", nptr->left, nptr->right);
}

/************************************/
/* list contens of a list on screen */
/************************************/
void show_list(struct listnode *listhead)
{
  while(listhead=listhead->next)
    shownode_list(listhead);
}