/*********************************************************************/
/* 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"

#if IRIX
  #include <stdlib.h>
  #include <unistd.h>
#endif
void insertnode_list();

/***************************************/
/* 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(nptr)
     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(sourcelist)
     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(listhead, ltext, rtext)
     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(listhead, nptr)
     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(listhead, cptr)
     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;
}
/********************************************************/
/* search for a node that has cptr as a beginning       */
/* return: ptr to node on succes / NULL on failure      */
/********************************************************/
struct listnode *searchnode_list_begin(listhead, cptr)
     struct listnode *listhead;
     char *cptr;
{
  int i;
  while((listhead=listhead->next)) {
    if((i=strncmp(listhead->left, cptr, strlen(cptr)))==0 && (*(listhead->left+strlen(cptr))==' ' || *(listhead->left+strlen(cptr))=='\0'))
      return listhead;
    else if (i>0) 
      return NULL;
  }
  return NULL;
}

/************************************/
/* show contens of a node on screen */
/************************************/
void shownode_list(nptr)
     struct listnode *nptr;
{
  char temp[BUFFER_SIZE];
  sprintf(temp, "{%s}={%s}", nptr->left, nptr->right);
  tintin_puts2(temp, (struct session *)NULL);
}

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


struct listnode *search_node_with_wild(listhead, cptr)
     struct listnode *listhead;
     char *cptr;
{
  /* int i; */
  while((listhead=listhead->next)) {
    if(check_one_node(listhead->left, cptr))
      return listhead;
  }
  return NULL;
}

int check_one_node(text, action)
     char *text;
     char *action;
{
  char *temp, temp2[BUFFER_SIZE], *tptr;
  while (*text && *action) {
    if (*action=='*') {
      action++;
      temp=action;
      tptr=temp2;
      while(*temp && *temp !='*')
        *tptr++=*temp++;
      *tptr='\0';
      if (strlen(temp2)==0) 
        return TRUE;
      while(strncmp(temp2,text,strlen(temp2))!=0 && *text)
        text++;
    }
    else {
      temp=action;
      tptr=temp2;
      while (*temp && *temp !='*')
        *tptr++=*temp++;
      *tptr='\0';
      if(strncmp(temp2,text,strlen(temp2))!=0)
        return FALSE;
      else {
        text+=strlen(temp2);
        action+=strlen(temp2);
      }
    }
  }
  if (*text)
    return FALSE;
  else if ((*action=='*' && !*(action+1)) || !*action)
    return TRUE;
  return FALSE;
}