/* --------------------------------------------------------------------- */ /* BEGIN COPYRIGHT AND LICENSE NOTICE */ /* --------------------------------------------------------------------- */ /* ** Copyright (c) 2008, 2009 by Richard Harter. ** ** Permission is hereby granted, free of charge, to any person ** obtaining a copy of this software and associated documentation ** files , to deal in the Software without ** restriction, including without limitation the rights to use, ** copy, modify, merge, publish, distribute, sublicense, and/or ** sell copies of the Software, and to permit persons to whom the ** Software is furnished to do so, subject to the following ** conditions: ** ** The above copyright notice and this permission notice shall be ** included in copies of this software and in copies of substantial ** portions, whether or not the software has been modified. ** ** Derivative works shall include a notice that the software is a ** modified version of the copyrighted software. ** ** There is no guarantee that this software is useful for anything ** or that it is any way correct or of value. The author disclaims ** any responsibility for the consequences of using this software. ** */ /* --------------------------------------------------------------------- */ /* END COPYRIGHT AND LICENSE NOTICE */ /* --------------------------------------------------------------------- */ /* Programming and usage notes: ** ** Listpkg lists do not contain copies of the items in the lists; instead ** the nodes contain pointers to the items. Hence altering list contents ** (including deleting lists) does not affect the existence of the items ** in the list. ** */ #include "errmgr.h" #include "stgpool.h" #include "trace.h" #include "listpkg.h" static listnode_s * free_list = 0; static listnode_s * get_generic_node(); static size_t add_size = 123; static stgpool_s * nodepool = 0; static void free_generic_node(listnode_s * node); /* --------------------------------------------------------------------- */ /* PUBLIC FUNCTIONS */ /* */ /* append_to_list Appends one item to an existing list */ /* delete_list Deletes all itmes from an existing list */ /* merge_two_lists Merges two lists, emptying the original lists*/ /* pop_from_list Pops one item from an existing list */ /* prepend_to_list Prepends one item to an existing list */ /* split_list_after_node Splits a list after a given node */ /* split_list_before_node Splits a list before a given node */ /* transfewr_list Transfers list contents from one to another */ /* */ /* --------------------------------------------------------------------- */ void append_to_list(listhdr_s * list, void *data) { listnode_s * node; trace("append_to_list"); node=get_generic_node(); if (!list->last) list->first = node; else list->last->link = node; node->data = data; node->link = 0; list->last = node; } listhdr_s prepend_to_list(listhdr_s list, void *data) { listnode_s * node; trace("prepend_to_list"); node=get_generic_node(); if (!list.first) list.last = node; node->data = data; node->link = list.first; list.first = node; return list; } void * pop_from_list(listhdr_s *list) { void * datum; listnode_s * node; trace("pop_from_list"); if (!list->first) return 0; node = list->first; datum = list->first->data; if (list->first == list->last) { list->first = 0; list->last = 0; } else { list->first = list->first->link; } free_generic_node(node); return datum; } listhdr_s merge_two_lists(listhdr_s * list1, listhdr_s * list2) { listnode_s * node; listhdr_s result; listhdr_s nil = {0}; trace("merge_two_lists"); if (!list1->first) result = *list2; else if (!list2->first) result = *list1; else { result = *list1; node = result.last; node->link = list2->first; result.last = list2->last; } *list1 = nil; *list2 = nil; return result; } listhdr_s split_list_before_node(listhdr_s *list, listnode_s * dnode) { listnode_s * node; listhdr_s tail = {0}; trace("split_list_before_node"); if (dnode &&list && list->first) { for (node=list->first ;node ;node = node->link) { if (node->link == dnode) { tail.first = dnode; tail.last = list->last; list->last = node; break; } } } return tail; } listhdr_s split_list_after_node(listhdr_s *list, listnode_s * dnode) { listhdr_s tail ={0}; trace("split_list_after_node"); if (dnode && list) { tail.first = dnode->link; list->last = dnode; } return tail; } void delete_list(listhdr_s * list) { trace("delete_list"); if (!list || !list->first) return; list->last->link = free_list; free_list = list->first; list->first = 0; list->last = 0; } listhdr_s transfer_list (listhdr_s *list) { listhdr_s out = {0}; trace("transfer_list"); if (list) { out = *list; list->first = 0; list->last = 0; } return out; } /* --------------------------------------------------------------------- */ /* PRIVATE FUNCTIONS */ /* --------------------------------------------------------------------- */ /* ** function: get_generic_node ** ** This function returns a generic node to the caller */ static listnode_s * get_generic_node() { listnode_s * node; listnode_s * nodes; int i; trace("get_generic_node"); if (!free_list) { nodes = stgpool_get(nodepool,add_size*sizeof(*nodes),LINELOC); for (i=1;ilink; node->link = 0; return node; } /* ** function: free_generic_node ** ** This function frees a generic node. */ void free_generic_node(listnode_s * node) { trace("free_generic_node"); if (node) { node->link = free_list; free_list = node; } }