/* Copyright (C) Magna Carta Software, Inc. 1991. All Rights Reserved C COMMUNICATIONS TOOLKIT LL.C -- Routines for handling linked lists of the form: struct mclink { struct mclink *next; struct mclink *prev; ... }; Note the ordering of 'next' and 'prev'. The 'mc' refers to 'Magna Carta' and exists solely to prevent name conflicts with your other code. Note: We call a function called 'memfree()' here. If you use these these routines outside CCT, just '#define memfree(a) free(a)' */ #include #include #include #include struct mclink { struct mclink *next; struct mclink *prev; }; typedef struct mclink * MCLINK; /* LL_APPEND_LINK -- Append a node to a linked list. Note that node->next is initialized to NULL; Parameters: void *base -- any node in the list; void *node -- the address of the node to append; Return Value: 0 -- success; EOF -- base is NULL; */ short ll_append_link(void *base, void *node) { MCLINK p; if (base == NULL) return (EOF); else { p = base; while (p->next != NULL) p = p->next; p->next = node; ((MCLINK) node)->prev = p; ((MCLINK) node)->next = NULL; } return (0); } /* LL_COUNT_LINKS -- Count the number of links in a linked list, starting at (but not including) the specified link. Parameters: void *base -- starting link; */ unsigned long ll_count_links(void *base) { MCLINK l = base; unsigned long i; for (i=0; l != NULL; i++) l = l->next; return (i); } /* LL_DELETE_LINK -- Delete a node from a linked list in the structure "mclink". The surrounding nodes are joined. Parameters: void **base -- the address of the beginning of the list; void *node -- the address of the node to append; Return Value: 0 -- success; EOF -- attempt to delete node at beginning of list; */ short ll_delete_link(void *node) { MCLINK p; if (node != NULL) { p = node; if (p->prev != NULL) { p->prev->next = p->next; if (p->next != NULL) p->next->prev = p->prev; memfree(p); } else return (EOF); } return (0); } /* LL_DELETE_LIST -- Delete all node from the present one to the end of the list. Parameters: void **base -- the address of the beginning of the list; void *node -- the address of the node to append; Return Value: 0 -- success; EOF -- attempt to delete node at beginning of list; */ short ll_delete_list(void *node) { MCLINK p; if (node != NULL) { p = node; if (p->next != NULL) do { p = p->next; memfree(p->prev); } while (p->next != NULL); memfree(p); } return (0); } /* LL_FIND_LINK -- Search forward for a specific link. Return value: * -- address of link number "pos"; NULL-- link not found; */ void * ll_find_link(void *base, void *node) { MCLINK l = base; while (l != NULL && l != node) l = l->next; return ((l == node) ? l : NULL); } /* LL_FIND_LINKNUM -- Search for link number "pos". Return value: * -- address of link number "pos"; NULL-- link not found; */ void * ll_find_linknum(void *base, unsigned short pos) { MCLINK l = base; unsigned short i = 0; if (l == NULL) return (NULL); while (l->next != NULL && i++ < pos) l = l->next; return ((i == pos) ? l : NULL); } /* LL_INSERT_LINK -- Insert a node into a linked list after the designated node. Parameters: void *base -- any node in the list; void *node -- the address of the node to append; Return Value: 0 -- success; EOF -- base is NULL; */ short ll_insert_link(void *base, void *node) { MCLINK p; if (base == NULL) return (EOF); else { p = base; ((MCLINK) node)->prev = p; ((MCLINK) node)->next = p->next; if (p->next != NULL) p->next->prev = node; p->next = node; } return (0); } #if 0 /* LL_SEARCH_LINK -- Search forward for a specific link based on a condition that applies to a link structure member. When condition is met, condition() should return 0. Else it should return a non-zero value. Return value: * -- address of link that meets "condition"; NULL-- link not found; */ void * ll_search_link(void *base, short (*condition)(void *node, char *s)) { MCLINK l = base; while (l != NULL) { if ((*condition)(l, s)) return (l); l = l->next; } return (NULL); } #endif