/* Autoconf patching by David Hedbor, neotron@lysator.liu.se */
/*********************************************************************/
/* 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 */
/*********************************************************************/
#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#include "tintin.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
void insertnode_list();
int match();
/***************************************/
/* 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->pr);
free(nptr);
}
}
/********************************************************************
** This function will clear all lists associated with a session **
********************************************************************/
void kill_all(ses, mode)
struct session *ses;
int mode;
{
switch (mode) {
case CLEAN:
if (ses != NULL) {
kill_list(ses->aliases);
ses->aliases=init_list();
kill_list(ses->actions);
ses->actions=init_list();
kill_list(ses->myvars);
ses->myvars=init_list();
kill_list(ses->highs);
ses->highs=init_list();
kill_list(ses->subs);
ses->subs=init_list();
kill_list(ses->antisubs);
ses->antisubs=init_list();
/* CHANGED to kill path stuff as well */
kill_list(ses->path);
ses->path=init_list();
kill_list(ses->pathdirs);
ses->pathdirs=init_list();
tintin_puts("Lists cleared.", ses);
prompt(NULL);
} else {
tintin_puts("Can't clean the common lists (yet):", NULL);
prompt(NULL);
}
break;
case END:
if (ses != NULL) {
kill_list(ses->aliases);
kill_list(ses->actions);
kill_list(ses->myvars);
kill_list(ses->highs);
kill_list(ses->subs);
kill_list(ses->antisubs);
kill_list(ses->path);
kill_list(ses->pathdirs);
} /* If */
break;
} /* Switch */
}
/***********************************************/
/* make a copy of a list - return: ptr to copy */
/***********************************************/
struct listnode *copy_list(sourcelist, mode)
struct listnode *sourcelist;
{
struct listnode *resultlist;
resultlist=init_list();
while((sourcelist=sourcelist->next))
insertnode_list(resultlist, sourcelist->left, sourcelist->right,
sourcelist->pr, mode);
return(resultlist);
}
/*****************************************************************/
/* create a node containing the ltext, rtext fields and stuff it */
/* into the list - in lexicographical order, or by numerical */
/* priority (dependent on mode) - Mods by Joann Ellsworth 2/2/94 */
/*****************************************************************/
void insertnode_list(listhead, ltext, rtext, prtext, mode)
struct listnode *listhead;
char *ltext;
char *rtext;
char *prtext;
int mode;
{
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);
newnode->pr=(char *)malloc(strlen(prtext)+1);
strcpy(newnode->left, ltext);
strcpy(newnode->right, rtext);
strcpy(newnode->pr, prtext);
nptr=listhead;
switch (mode) {
case PRIORITY:
while((nptrlast=nptr) && (nptr=nptr->next)) {
if(strcmp(prtext, nptr->pr)<0) {
newnode->next=nptr;
nptrlast->next=newnode;
return;
} else
if (strcmp(prtext, nptr->pr)==0) {
while ((nptrlast) && (nptr) &&
(strcmp(prtext, nptr->pr)==0)) {
if(strcmp(ltext, nptr->left)<=0) {
newnode->next=nptr;
nptrlast->next=newnode;
return;
}
nptrlast=nptr;
nptr=nptr->next;
}
nptrlast->next=newnode;
newnode->next=nptr;
return;
}
}
nptrlast->next=newnode;
newnode->next=NULL;
return;
break;
case ALPHA:
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;
return;
break;
} /* Switch */
}
/*****************************/
/* 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->pr);
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;
/* CHANGED to fix bug when list isn't alphabetically sorted
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 */
/* Mods made by Joann Ellsworth - 2/2/94 */
/********************************************************/
struct listnode *searchnode_list_begin(listhead, cptr, mode)
struct listnode *listhead;
char *cptr;
int mode;
{
int i;
switch (mode) {
case PRIORITY:
while((listhead=listhead->next)) {
if((i=strncmp(listhead->left, cptr, strlen(cptr)))==0 &&
(*(listhead->left+strlen(cptr))==' ' ||
*(listhead->left+strlen(cptr))=='\0'))
return listhead;
}
return NULL;
break;
case ALPHA:
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;
break;
}
}
/************************************/
/* 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);
}
void shownode_list_action(nptr)
struct listnode *nptr;
{
char temp[BUFFER_SIZE];
sprintf(temp, "{%s}={%s} @ {%s}", nptr->left, nptr->right, nptr->pr);
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);
}
void show_list_action(listhead)
struct listnode *listhead;
{
while((listhead=listhead->next))
shownode_list_action(listhead);
}
struct listnode *search_node_with_wild(listhead, cptr)
struct listnode *listhead;
char *cptr;
{
/* int i; */
while((listhead=listhead->next)) {
/* CHANGED to fix silly globbing behavior
if(check_one_node(listhead->left, cptr))
*/
if(match(cptr, listhead->left))
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;
}
/*********************************************************************/
/* create a node containint the ltext, rtext fields and place at the */
/* end of a list - as insertnode_list(), but not alphabetical */
/*********************************************************************/
void addnode_list(listhead, ltext, rtext, prtext)
struct listnode *listhead;
char *ltext;
char *rtext;
char *prtext;
{
struct listnode *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);
newnode->pr=(char *)malloc(strlen(prtext)+1);
newnode->next=NULL;
strcpy(newnode->left, ltext);
strcpy(newnode->right, rtext);
strcpy(newnode->pr, prtext);
while (listhead->next!=NULL) (listhead=listhead->next);
listhead->next=newnode;
}
int count_list(listhead)
struct listnode *listhead;
{
int count=0;
struct listnode *nptr;
nptr=listhead;
while (nptr=nptr->next)
++count;
return(count);
}