Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

list.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Copyright 2005 Daniel Ferullo                                             *
00003  *                                                                           *
00004  * Licensed under the Apache License, Version 2.0 (the "License");           *
00005  * you may not use this file except in compliance with the License.          *
00006  * You may obtain a copy of the License at                                   *
00007  *                                                                           *
00008  *    http://www.apache.org/licenses/LICENSE-2.0                             *
00009  *                                                                           *
00010  * Unless required by applicable law or agreed to in writing, software       *
00011  * distributed under the License is distributed on an "AS IS" BASIS,         *
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
00013  * See the License for the specific language governing permissions and       *
00014  * limitations under the License.                                            *
00015  *                                                                           *
00016  *****************************************************************************/
00017 
00018 /**
00019  * @file list.c
00020  * @author Daniel Ferullo (ferullo@cmu.edu)
00021  *
00022  * @brief A basic list implementation (optimized for sequential accesses).
00023  */
00024 
00025 #include "list.h"
00026 #include "util.h"
00027 #include "debug.h"
00028 
00029 errorcode list_init(list_t *list) {
00030 
00031         if (list==NULL)
00032                 return ERROR_NULL_ARG_1;
00033 
00034         list->head=NULL;
00035         list->last_get = list->head;
00036         list->last_get_num = 0;
00037         list->size = 0;
00038 
00039         return SUCCESS;
00040 }
00041 
00042 errorcode list_destroy(list_t *list, void (*func)(void*,void*), void *arg) {
00043 
00044         list_node_t *node;
00045 
00046         if (list==NULL)
00047                 return ERROR_NULL_ARG_1;
00048 
00049         while (list->head != NULL) {
00050                 /* make this node point to the old head */
00051                 node = list->head;
00052                 /* set the 2nd node to be the first now */
00053                 list->head = node->next;
00054                 /* use user defined function to clean up item */
00055                 if (func!=NULL)
00056                         func(node->item,arg);
00057                 /* delete the old first node */
00058                 safe_free(node);
00059         }
00060 
00061         return SUCCESS;
00062 }
00063 
00064 errorcode list_find(list_t *list, int (*func)(void*,void*), void *arg,
00065                     void**found_item) {
00066 
00067         list_node_t *node;
00068 
00069         if (list==NULL)
00070                 return ERROR_NULL_ARG_1;
00071         if (func==NULL)
00072                 return ERROR_NULL_ARG_2;
00073         if (found_item==NULL)
00074                 return ERROR_NULL_ARG_4;
00075 
00076         node = list->head;
00077 
00078         while(node!=NULL) {
00079                 switch (func(node->item,arg)) {
00080                         case LIST_FATAL :
00081                                 return ERROR_FUNC_POINTER_FUNC_FAILED;
00082                         case LIST_NOT_FOUND :
00083                                 node = node->next;
00084                                 break;
00085                         case LIST_FOUND :
00086                                 *found_item = node->item;
00087                                 return SUCCESS;
00088                         default :
00089                                 return ERROR_FUNC_POINTER_FUNC_INVALID;
00090                 }
00091         }
00092 
00093         return ERROR_NOT_FOUND;
00094 }
00095 
00096 errorcode list_get(list_t *list, int index, void **item) {
00097 
00098         list_node_t *node, *start;
00099         int num;
00100 
00101         if (list==NULL)
00102                 return ERROR_NULL_ARG_1;
00103         if (index<0)
00104                 return ERROR_NEG_ARG_2;
00105         if (item==NULL)
00106                 return ERROR_NULL_ARG_3;
00107         if (index>list->size)
00108                 return ERROR_ARG_2;
00109 
00110         start = node = list->last_get;
00111         num = list->last_get_num;
00112 
00113         do {
00114                 /* if this is the end of the list, loop back to begining */
00115                 if (node==NULL) {
00116                         node = list->head;
00117                         num = 0; /*reset the counter */
00118                         continue;
00119                 }
00120                 /* if this is the index item, return it */
00121                 if (num==index) {
00122                         *item = node->item;
00123                         list->last_get = node;
00124                         list->last_get_num = index;
00125                         return SUCCESS;
00126                 }
00127                 node = node->next;
00128                 num++;
00129         } while (start!=node); /* loop until the entire list was searched */
00130 
00131         return ERROR_NOT_FOUND;
00132 }
00133 
00134 errorcode list_add(list_t *list, void *item) {
00135 
00136         list_node_t *node;
00137 
00138         if (list==NULL)
00139                 return ERROR_NULL_ARG_1;
00140 
00141         if ( (node=(list_node_t*)malloc(sizeof(list_node_t))) == NULL)
00142                 return ERROR_MALLOC_FAILED;
00143 
00144         /* set this node's item */
00145         node->item = item;
00146         /* make this node point to the old head */
00147         node->next = list->head;
00148         /* make this node the head of the list */
00149         list->head = node;
00150 
00151         /*reset the last_get pointer */
00152         list->last_get = list->head;
00153         list->last_get_num = 0;
00154         /* increase list size */
00155         list->size += 1;
00156 
00157         return SUCCESS;
00158 }
00159 
00160 errorcode list_remove(list_t *list, int (*func)(void*,void*), void *arg){
00161 
00162         list_node_t *node;
00163         list_node_t *prev_node;
00164 
00165         if (list==NULL)
00166                 return ERROR_NULL_ARG_1;
00167         if (func==NULL)
00168                 return ERROR_NULL_ARG_2;
00169 
00170         prev_node = NULL;
00171         node = list->head;
00172 
00173         while(node!=NULL) {
00174                 switch (func(node->item,arg)) {
00175                         /* if there was a fatal error, handle it */
00176                         case LIST_FATAL :
00177                                 return ERROR_FUNC_POINTER_FUNC_FAILED;
00178                         /* if this just wasn't the item look at the next one */
00179                         case LIST_NOT_FOUND :
00180                                 prev_node = node;
00181                                 node = node->next;
00182                                 break;
00183                         /* if the item was found, remove it*/
00184                         case LIST_FOUND :
00185                                 /* if this is the first item to remove, set the head */
00186                                 if (prev_node==NULL)
00187                                         list->head = node->next;
00188                                 /* otherwise, set the previous node's next value to the
00189                                  * next node */
00190                                 else
00191                                         prev_node->next = node->next;
00192                                 /* now free the node */
00193                                 safe_free(node);
00194                                 /* reset the last get pointer */
00195                                 list->last_get = list->head;
00196                                 list->last_get_num = 0;
00197                                 /* decrease list size */
00198                                 list->size -= 1;
00199                                 return SUCCESS;
00200                         default :
00201                                 return ERROR_FUNC_POINTER_FUNC_INVALID;
00202                 }
00203         }
00204 
00205         return ERROR_NOT_FOUND;
00206 }
00207 
00208 int list_count(list_t *list) {
00209 
00210         if (list==NULL)
00211                 return -1;
00212         return list->size;
00213 }
00214 

Generated on Wed Mar 30 23:20:47 2005 for NATBLASTER by  doxygen 1.3.9.1