Mercurial > pidgin
diff plugins/icq/list.c @ 1152:201ec77f3a60
[gaim-migrate @ 1162]
icq. whoop de doo
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 28 Nov 2000 02:22:42 +0000 |
parents | |
children | 0a766047b4fd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/icq/list.c Tue Nov 28 02:22:42 2000 +0000 @@ -0,0 +1,273 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* +$Id: list.c 1162 2000-11-28 02:22:42Z warmenhoven $ +$Log$ +Revision 1.1 2000/11/28 02:22:42 warmenhoven +icq. whoop de doo + +Revision 1.14 2000/07/10 01:44:20 bills +i really don't learn - removed LIST_TRACE define + +Revision 1.13 2000/07/10 01:43:48 bills +argh - last list buglet fixed, removed free(node) call from list_free + +Revision 1.12 2000/07/10 01:31:17 bills +oops - removed #define LIST_TRACE and #define QUEUE_DEBUG + +Revision 1.11 2000/07/10 01:26:30 bills +added more trace messages, added list_remove_node call in list_free... +fixes list corruption bug introduced during last commit + +Revision 1.10 2000/07/09 22:04:45 bills +recoded list_free function - this was working very incorrectly! it was +only freeing the first node of the list, and then ending. fixes a memory +leak. + +Revision 1.9 2000/05/10 18:48:56 denis +list_free() was added to free but do not dispose the list. +Memory leak with destroying the list was fixed. + +Revision 1.8 2000/05/03 18:19:15 denis +Bug with empty contact list was fixed. + +Revision 1.7 2000/01/16 21:26:54 bills +fixed serious bug in list_remove + +Revision 1.6 2000/01/16 03:59:10 bills +reworked list code so list_nodes don't need to be inside item structures, +removed strlist code and replaced with generic list calls + +Revision 1.5 1999/09/29 19:59:30 bills +cleanups + +Revision 1.4 1999/07/16 11:59:46 denis +list_first(), list_last(), list_at() added. +Cleaned up. + +*/ +/* + * linked list functions + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "list.h" + +list *list_new() +{ + list *plist=(list *)malloc(sizeof(list)); + + plist->head=0; + plist->tail=0; + plist->count=0; + + return plist; +} + +/* Frees all list nodes and list itself */ +void list_delete(list *plist, void (*item_free_f)(void *)) +{ + list_free(plist, item_free_f); + free(plist); +} + +/* Only frees the list nodes */ +void list_free(list *plist, void (*item_free_f)(void *)) +{ + list_node *p=plist->head; + +#ifdef LIST_TRACE + printf("list_free(%p)\n", plist); + list_dump(plist); +#endif + + while(p) + { + list_node *ptemp=p; + + p=p->next; + (*item_free_f)((void *)ptemp->item); + list_remove_node(plist, ptemp); + } +} + +void list_insert(list *plist, list_node *pnode, void *pitem) +{ + list_node *pnew=(list_node *)malloc(sizeof(list_node)); + pnew->item=pitem; + +#ifdef LIST_TRACE + printf("inserting %x (node=%x) into list %x\n", pitem, pnew, plist); +#endif + + plist->count++; + + /* null source node signifies insert at end of list */ + if(!pnode) + { + pnew->previous=plist->tail; + pnew->next=0; + if(plist->tail) + plist->tail->next=pnew; + plist->tail=pnew; + + if(!plist->head) + plist->head=pnew; + } + else + { + pnew->previous=pnode->previous; + pnew->next=pnode; + + if(pnew->previous) + pnew->previous->next=pnew; + + if(pnew->next) + pnode->previous=pnew; + + if(plist->head==pnode) + plist->head=pnew; + } + +#ifdef LIST_TRACE + list_dump(plist); +#endif +} + +void *list_remove_node(list *plist, list_node *p) +{ + void *pitem; + + if(!p) + return 0; + +#ifdef LIST_TRACE + printf("removing %x (node=%x) from list %x\n", p->item, p, plist); +#endif + + plist->count--; + + if(p->next) + p->next->previous=p->previous; + + if(p->previous) + p->previous->next=p->next; + + if(plist->head==p) + plist->head=p->next; + + if(plist->tail==p) + plist->tail=p->previous; + + p->next=0; + p->previous=0; + +#ifdef LIST_TRACE + list_dump(plist); +#endif + + pitem=p->item; + + free(p); + + return pitem; +} + +void *list_traverse(list *plist, int (*item_f)(void *, va_list), ...) +{ + list_node *i=plist->head; + int f=0; + va_list ap; + +#ifdef LIST_TRACE + printf("list_traverse(%p)\n", plist); + list_dump(plist); +#endif + va_start(ap, item_f); + + /* call item_f for each item in list until end of list or item + * function returns 0 */ + while(i && !f) + { + list_node *pnext=i->next; + + if(!(f=(*item_f)(i->item, ap))) + i=pnext; + } + va_end(ap); + if (i) + return i->item; + else + return 0; +} + +int list_dump(list *plist) +{ + list_node *p=plist->head; + + printf("list %x { head=%x, tail=%x, count=%d }\ncontents: ", + (int)plist, (int)plist->head, (int)plist->tail, plist->count); + + while(p) + { + printf("%x, ", (int)p->item); + p=p->next; + } + printf("end\n"); + + return 0; +} + +void *list_first(list *plist) +{ + if(plist->head) + return plist->head->item; + else + return 0; +} + +void *list_last(list *plist) +{ + if(plist->tail) + return plist->tail->item; + else + return 0; +} + +void *list_at(list *plist, int num) +{ + list_node *ptr = plist->head; + while(ptr && num) + { + num--; + ptr = ptr->next; + } + if(!num) + return ptr->item; + else + return 0L; +} + +list_node *list_find(list *plist, void *pitem) +{ + list_node *p=plist->head; + + while(p) + { + if(p->item==pitem) + return p; + p=p->next; + } + return 0; +} + +void *list_remove(list *plist, void *pitem) +{ + list_node *p=list_find(plist, pitem); + + if(p) + return list_remove_node(plist, p); + else + return 0; +}