/* /* button.c /* /* Author: ScoTT Campbell /* Date: 28/8/98 /* /* Most of these functions will only work to their definitions if lists are /* created and manipulated solely with this package /* /* i.e. Manipulating lists outwith these functions WILL produce undefined behaviour. */ #include "button.h" #ifndef _MALLOC_H #include #endif #define NULL_BUTTON_NODE ((void*) 0) button_list CreateButtonList() /* Returns a pointer to an initialised new empty button list */ { /* Try and allocate memory in heap for new list */ button_list newList = (button_list) malloc(sizeof(button_list_head)); /* If memory has been allocated then initialise the structure */ if(newList != NULL_BUTTON_LIST) { newList->front = newList->back = newList->current = NULL_BUTTON_NODE; newList->length = 0; } return newList; } int BLClear(button_list list) /* Removes all nodes from a list */ /* Returns 0 when the list is empty; returns 0 if there was a problem */ { button_type button; if(list != NULL_BUTTON_LIST) { while(!BLGetFront(list, &button)) /* Make sure the list is empty */ list->front = list->current = list->back = NULL_BUTTON_NODE; list->length = 0; return 0; } else return 1; } int BLIsEmpty(button_list list) /* Returns 1 if list is empty; 0 otherwise */ /* Assumes that list has been manipulated only by this package */ { return !(list->length); } int BLLength(button_list list) /* Returns the number of nodes in list */ /* Assumes that list has been manipulated only by this package */ { return list->length; } /* Following functions return 0 if succesful; 1 otherwise */ int BLAddFront(button_list list, button_type button) /* Adds node to front of list and stores value of button in it */ { /* Try to get space on heap for a new node */ button_list_node_ptr newNodePtr = (button_list_node_ptr) malloc(sizeof(button_list_node)); /* Check that list is not null and node has been allocated memory */ if((list != NULL_BUTTON_LIST) && (newNodePtr != NULL_BUTTON_NODE)) { /* Put value we want to store into new node */ newNodePtr->buttonValue = button; /* Put the new node to front of the list */ newNodePtr->next = list->front; newNodePtr->previous = NULL_BUTTON_NODE; list->front->previous = newNodePtr; list->front = newNodePtr; list->length++; /* If this is the only node then fix the back pointer */ if(list->length == 1) list->back = newNodePtr; return 0; } else return 1; } int BLAddBack(button_list list, button_type button) /* Adds node to back of list and stores value of button in it */ { /* Try to get space on heap for a new node */ button_list_node_ptr newNodePtr = (button_list_node_ptr) malloc(sizeof(button_list_node)); /* Check that list is not null and node has been allocated memory */ if((list != NULL_BUTTON_LIST) && (newNodePtr != NULL_BUTTON_NODE)) { /* Put value we want to store into new node */ newNodePtr->buttonValue = button; /* Put the new node to back of the list */ newNodePtr->next = NULL_BUTTON_NODE; newNodePtr->previous = list->back; list->back->next = newNodePtr; list->back = newNodePtr; list->length++; /* If this is the only node then fix the front pointer */ if(list->length == 1) list->front = newNodePtr; return 0; } else return 1; } int BLAddBehindCurrent(button_list list, button_type button) /* Adds node behind the current node and stores button in it */ { /* Try to get space on heap for a new node */ button_list_node_ptr newNodePtr = (button_list_node_ptr) malloc(sizeof(button_list_node)); /* Check that list is not null, node has been allocated memory, and list->current points to a node */ if((list != NULL_BUTTON_LIST) && (newNodePtr != NULL_BUTTON_NODE) && (list->current != NULL_BUTTON_NODE)) { /* Put value we want to store into new node */ newNodePtr->buttonValue = button; /* Put the new node to back of the list */ newNodePtr->next = list->current->next; newNodePtr->previous = list->current; list->current->next = newNodePtr; list->length++; return 0; } else return 1; } int BLAddInFrontCurrent(button_list list, button_type button) /* Adds node in front of the current node and stores button in it */ { /* Try to get space on heap for a new node */ button_list_node_ptr newNodePtr = (button_list_node_ptr) malloc(sizeof(button_list_node)); /* Check that list is not null, node has been allocated memory, and list->current points to a node */ if((list != NULL_BUTTON_LIST) && (newNodePtr != NULL_BUTTON_NODE) && (list->current != NULL_BUTTON_NODE)) { /* Put value we want to store into new node */ newNodePtr->buttonValue = button; /* Put the new node to back of the list */ newNodePtr->next = list->current; newNodePtr->previous = list->current->previous; list->current->previous = newNodePtr; list->length++; return 0; } else return 1; } int BLGetFront(button_list list, button_type* buttonPtr) /* Removes node from front of list and puts the value held into *buttonPtr */ { /* Get a pointer to the node we want to remove */ button_list_node_ptr wantedNodePtr = list->front; /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (wantedNodePtr != NULL_BUTTON_NODE)) { /* Remove node from list */ list->front = list->front->next; /* If list is now empty then sort tail and current pointers */ list->length--; if(list->length == 0) list->front = list->back = list->current = NULL_BUTTON_NODE; /* Get the value we are after */ *buttonPtr = wantedNodePtr->buttonValue; /* Release the memory from the heap */ free((void*)wantedNodePtr); return 0; } else return 1; } int BLGetBack(button_list list, button_type* buttonPtr) /* Removes node from back of list and puts the value held into *buttonPtr */ { /* Get a pointer to the node we want to remove */ button_list_node_ptr wantedNodePtr = list->back; /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (wantedNodePtr != NULL_BUTTON_NODE)) { /* Remove node from list */ list->back = list->back->previous; /* If list is now empty then sort head and current pointer */ list->length--; if(list->length == 0) list->front = list->current = list->back = NULL_BUTTON_NODE; /* Get the value we are after */ *buttonPtr = wantedNodePtr->buttonValue; /* Release the memory from the heap */ free((void*)wantedNodePtr); return 0; } else return 1; } int BLGetCurrent(button_list list, button_type* buttonPtr) /* Removes node pointed to by list->current and puts the value held into *buttonPtr */ { /* Get a pointer to the node we want to remove */ button_list_node_ptr wantedNodePtr = list->current; /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (wantedNodePtr != NULL_BUTTON_NODE)) { /* Remove node from list */ list->current->previous->next = list->current->next; list->current = list->current->next->previous = list->current->previous; /* If list is now empty then sort head and tail pointers */ list->length--; if(list->length == 0) list->front = list->back = NULL_BUTTON_NODE; /* Get the value we are after */ *buttonPtr = wantedNodePtr->buttonValue; /* Release the memory from the heap */ free((void*)wantedNodePtr); return 0; } else return 1; } int BLReturnFront(button_list list, button_type* buttonPtr) /* Puts value held at front of list into *buttonPtr without affecting the list*/ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->front != NULL_BUTTON_NODE)) { /* Copy the value we want into *buttonPtr */ *buttonPtr = list->front->buttonValue; return 0; } else return 1; } int BLReturnBack(button_list list, button_type* buttonPtr) /* Puts value held at back of list into *buttonPtr without affecting the list */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->back != NULL_BUTTON_NODE)) { /* Copy the value we want into *buttonPtr */ *buttonPtr = list->back->buttonValue; return 0; } else return 1; } int BLReturnCurrent(button_list list, button_type* buttonPtr) /* Puts value held ad node pointed to by current pointer into *arg2 */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->current != NULL_BUTTON_NODE)) { /* Copy the value we want into *buttonPtr */ *buttonPtr = list->current->buttonValue; return 0; } else { return 1; } } int BLSetCurrentToFront(button_list list) /* Sets current pointer to the value of the front pointer */ { if(list != NULL_BUTTON_LIST) { list->current = list->front; return 0; } else return 1; } int BLSetCurrentToBack(button_list list) /* Sets current pointer to the value of the front pointer */ { if(list != NULL_BUTTON_LIST) { list->current = list->back; return 0; } else return 1; } int BLAdvanceCurrent(button_list list) /* Moves the current pointer to the next node */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->current != NULL_BUTTON_NODE)) { /* Advance the front pointer up the list */ list->current = list->current->next; return 0; } else return 1; } int BLRetreatCurrent(button_list list) /* Moves the current pointer to the previous node */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->current != NULL_BUTTON_NODE)) { /* Advance the front pointer up the list */ list->current = list->current->next; return 0; } else return 1; } /* Following functions will not move the head or tail pointers off of the list */ /* This is to ensure that they never become NULL_BUTTON_NODEs , but means that */ /* users of this package are responsible for checking when the end of the list */ /* has been reached. I suggest checking that the list is not empty, then */ /* waiting for the functions to return 1. */ /* */ /* i.e. if(!BLIsEmpty(list)) */ /* while(!BLAdvanceHead(list)); */ /* */ /* This will ensure that failure can only occur when trying to move the head or */ /* tail pointers off the list. */ int BLAdvanceHead(button_list list) /* Moves the list->front pointer to the next node if possible */ /* Does not affect the structure or length of the list */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->front != NULL_BUTTON_NODE) && (list->front->next != NULL_BUTTON_NODE)) { /* Advance the front pointer up the list */ list->front = list->front->next; return 0; } else return 1; } int BLRetreatHead(button_list list) /* Moves the list->front pointer to the previous node if possible */ /* Does not affect the structure or length of the list */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->front != NULL_BUTTON_NODE) && (list->front->previous != NULL_BUTTON_NODE)) { /* Retreat the pointer back along the list */ list->front = list->front->previous; return 0; } else return 1; } int BLAdvanceTail(button_list list) /* Moves the list->back pointer to the next node if possible */ /* Does not affect the structure or length of the list */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->back != NULL_BUTTON_NODE) && (list->back->next != NULL_BUTTON_NODE)) { /* Advance the pointer back along the list */ list->back = list->back->next; return 0; } else return 1; } int BLRetreatTail(button_list list) /* Makes the previous node the back of the list */ /* Does not affect the structure or length of the list */ { /* Check we are about to perform a valid operation */ if((list != NULL_BUTTON_LIST) && (list->back != NULL_BUTTON_NODE) && (list->back->previous != NULL_BUTTON_NODE)) { /* Retreat the pointer along the list */ list->back = list->back->previous; return 0; } else return 1; } int BLResetHeadAndTail(button_list list) /* Moves the list->front and list->back pointers */ /* to the head and tail of the list respectively, if possible*/ { if((list != NULL_BUTTON_LIST) && (list->front != NULL_BUTTON_NODE) && (list->back != NULL_BUTTON_NODE)) { /* reset the front pointer */ while(list->front->previous != NULL_BUTTON_LIST) list->front = list->front->previous; /* reset back pointer */ while(list->back->next != NULL_BUTTON_LIST) list->back = list->back->next; return 0; } else return 1; }