Changeset 460
- Timestamp:
- Apr 19, 2004, 3:38:34 PM (22 years ago)
- Location:
- trunk/psLib/src/sysUtils
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sysUtils/psDList.c
r454 r460 1 /* 2 * Minimal support for doubly linked lists 3 */ 1 /** @file psDlist.h 2 * @brief Support for doubly linked lists 3 * @ingroup DataContainers 4 * 5 * @author Robert Lupton, Princeton University 6 * @author Robert Daniel DeSonia, MHPCC 7 * 8 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2004-04-20 01:38:34 $ 10 * 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 12 */ 13 4 14 #include <stdlib.h> 5 15 #include <stdio.h> 6 16 #include <assert.h> 7 #include "psLib.h" 17 #include "psError.h" 18 #include "psAbort.h" 19 #include "psMemory.h" 20 #include "psDList.h" 21 #include "psTrace.h" 8 22 9 23 static psDlistElem *dlistElemAlloc(void) … … 17 31 } 18 32 19 /*****************************************************************************/ 20 21 psDlist *psDlistAlloc(void *data) // initial data item; may be NULL 33 psDlist *psDlistAlloc(void *data) 22 34 { 23 35 psDlist *list = psAlloc(sizeof(psDlist)); … … 26 38 list->head = list->tail = NULL; 27 39 list->iter = NULL; 28 if (data != NULL)29 {40 list->iterIndex = 0; 41 if (data != NULL) { 30 42 psDlistAdd(list, data, PS_DLIST_TAIL); 31 43 } … … 34 46 } 35 47 36 void psDlistFree(psDlist *list, // list to destroy 37 void (*elemFree)(void *)) // destructor for data on list 38 { 39 if (list == NULL) 40 { 48 void psDlistFree(psDlist *list, void (*elemFree)(void *)) 49 { 50 if (list == NULL) { 41 51 return; 42 52 } 43 53 44 psDlistElem *ptr = list->head; 45 while (ptr != NULL) 46 { 54 for(psDlistElem *ptr = list->head; ptr != NULL; ) { 47 55 psDlistElem *next = ptr->next; 48 56 … … 60 68 } 61 69 62 /*****************************************************************************/ 63 /* 64 * Add an element to a list 65 */ 66 psDlist *psDlistAdd(psDlist *list, // list to add to; may be NULL 67 void *data, // data to add 68 int where) // where to add data. PS_DLIST_HEAD, 69 // PS_DLIST_TAIL, or an integer 70 psDlist *psDlistAdd(psDlist *list, void *data, int where) 70 71 { 71 72 psDlistElem *elem = dlistElemAlloc(); 72 73 73 if (list == NULL) 74 { 74 if (list == NULL) { 75 75 list = psDlistAlloc(NULL); 76 76 } 77 77 78 if (where > list->n) 79 { // XXX need better diagnostic here 80 fprintf(stderr, "Invalid index %d (only %d elements)\n", 81 where, list->n); 82 dlistElemFree(elem); // cleanup 78 if (where > list->n) { 79 psError(__FILE__, "Invalid index %d (only %d elements in psDList).", where, list->n); 80 dlistElemFree(elem); // cleanup just allocated element 83 81 84 82 return list; 85 83 } 86 84 87 if (where == PS_DLIST_HEAD) 88 { // easy 85 if (where == PS_DLIST_HEAD) { 89 86 elem->prev = NULL; 90 87 elem->next = list->head; … … 100 97 } 101 98 list->n++; 102 } else if (where == PS_DLIST_TAIL) 103 { // also easy 99 } else if (where == PS_DLIST_TAIL) { 104 100 elem->prev = list->tail; 105 101 elem->next = NULL; … … 115 111 } 116 112 list->n++; 117 } else 118 { // XXX 119 fprintf(stderr, "Insertion into psDlists is not yet supported\n"); 120 return psDlistAdd(list, data, PS_DLIST_TAIL); 113 } else if (where == PS_DLIST_PREVIOUS) { 114 if (list->iter == NULL) { // if no position, just insert it in the front of the list. 115 return psDlistAdd(list,data,PS_DLIST_HEAD); 116 } 117 elem->prev = list->iter->prev; 118 elem->next = list->iter; 119 elem->data = psMemIncrRefCounter(data); 120 121 list->iter->prev = elem; 122 if (elem->prev != NULL) { 123 elem->prev->next = elem; 124 } 125 126 list->n++; 127 } else if (where == PS_DLIST_NEXT) { 128 if (list->iter == NULL) { 129 return psDlistAdd(list,data,PS_DLIST_TAIL); 130 } 131 elem->prev = list->iter; 132 elem->next = list->iter->next; 133 elem->data = psMemIncrRefCounter(data); 134 135 list->iter->next = elem; 136 if (elem->next != NULL) { 137 elem->next->prev = elem; 138 } 139 140 list->n++; 141 } else if (where < 0) { 142 /// XXX What is the best way to communicate this failure to the caller? 143 psError(__func__,"The given insert location (%i) for psDlistAdd is invalid.",where); 144 } else { 121 145 } 122 146 … … 156 180 } 157 181 158 psTrace( "utils.dlist.remove", 5, "Failed to find 0x%x on psDlist 0x%x", data, list);182 psTrace(__FILE__, 5, "Failed to find 0x%x on psDlist 0x%x", data, list); 159 183 160 184 return NULL; … … 199 223 200 224 if (which < 0 || which >= list->n) { // out of bounds 201 psError(__func__, PS_ERR_BAD_INDEX, 1,"Index %d is not in range [0..%d] for list 0x%x", which, list->n,225 psError(__func__,"Index %d is not in range [0..%d] for list 0x%x", which, list->n, 202 226 list); 203 227 return NULL; … … 229 253 * 230 254 * If which is psDlist{Next,Prev} return the next/previous 231 * data and move the iteration cursor 232 * 233 * If which is psDlist{Head,Tail} initiali se the iteration pointer255 * data and move the iteration cursor 256 * 257 * If which is psDlist{Head,Tail} initialize the iteration pointer 234 258 * and return the head/tail 235 259 * … … 239 263 #define ITER_INIT_TAIL ((void *)2) // next iteration should return tail 240 264 241 void *psDlistGet( 242 const psDlist *list, // list to retrieve element from 243 i nt which) // index of item, or PS_DLIST_NEXT,244 // or PS_DLIST_PREV 245 { 246 assert (list != NULL);265 void *psDlistGet(const psDlist *list, int which) 266 { 267 if (list == NULL) { 268 psError(__func__,"Unexpected null pointer for psDlist parameter (%s:%d).",__FILE__,__LINE__); 269 return NULL; 270 } 247 271 248 272 switch (which) { 249 case PS_DLIST_HEAD: // easy273 case PS_DLIST_HEAD: 250 274 ((psDlist *)list)->iter = ITER_INIT_HEAD; 251 275 return (list->head == NULL) ? NULL : list->head->data; 252 case PS_DLIST_TAIL: // also easy 276 277 case PS_DLIST_TAIL: 253 278 ((psDlist *)list)->iter = ITER_INIT_TAIL; 254 279 return (list->tail == NULL) ? NULL : list->tail->data; 255 case PS_DLIST_PREV: // use iterator 280 281 case PS_DLIST_PREVIOUS: // use iterator 256 282 case PS_DLIST_NEXT: 257 283 if (list->iter == NULL) { … … 261 287 } else if (list->iter == ITER_INIT_TAIL) { 262 288 ((psDlist *)list)->iter = list->tail; 263 } else if (which == PS_DLIST_PREV ) {289 } else if (which == PS_DLIST_PREVIOUS) { 264 290 ((psDlist *)list)->iter = list->iter->prev; 265 291 } else if (which == PS_DLIST_NEXT) { 266 292 ((psDlist *)list)->iter = list->iter->next; 267 293 } else { 268 fprintf(stderr,"You cannot get here\n"); 269 abort(); 294 psAbort(__func__,"Unreachable line was reached in %s:%d?",__FILE__,__LINE__); 270 295 } 271 296 … … 276 301 277 302 break; 278 default: // XXX 279 fprintf(stderr, 280 "Retrieval from psDlists by index is not yet supported\n"); 281 return NULL; 303 default: 304 if (which < 0) { 305 psError(__func__,"the position is invalid for %s",__func__); 306 return NULL; 307 } 308 ((psDlist *)list)->iter = list->head; 309 for (int i=0;i<which;i++) {} 310 311 if (list->iter == NULL) { 312 return NULL; 313 } 314 return list->iter->data; // XXX what if data is NULL? 282 315 } 283 316 } … … 289 322 * First a call to set the iteration pointer to the head of the list 290 323 */ 291 void psDlistSetIterator(psDlist *list, // the list in question 292 int where, // where on the list should I start? 293 int which) // @notused@ the desired iterator 294 { 295 if (where != PS_DLIST_HEAD && where != PS_DLIST_TAIL) 296 { 297 psError(__func__, PS_ERR_UNKNOWN, 1, "Invalid where argument: %d; assuming PS_DLIST_HEAD", where); 324 void psDlistSetIterator(psDlist *list, 325 int where) 326 { 327 if (where != PS_DLIST_HEAD && where != PS_DLIST_TAIL) { 328 psError(__func__, "Invalid where argument: %d; assuming PS_DLIST_HEAD", where); 298 329 where = PS_DLIST_HEAD; 299 330 } … … 305 336 * and now return the previous/next element of the list 306 337 */ 307 void *psDlistGetNext(psDlist *list, // the list in question 308 int which) // @notused@ the desired iterator 338 void *psDlistGetNext(psDlist *list) 309 339 { 310 340 return psDlistGet(list, PS_DLIST_NEXT); 311 341 } 312 342 313 void *psDlistGetPrev(psDlist *list, // the list in question 314 int which) // @notused@ the desired iterator 315 { 316 return psDlistGet(list, PS_DLIST_PREV); 317 } 318 319 /*****************************************************************************/ 343 void *psDlistGetPrevious(psDlist *list) 344 { 345 return psDlistGet(list, PS_DLIST_PREVIOUS); 346 } 347 348 void *psDlistGetCurrent(psDlist *list) 349 { 350 return psDlistGet(list, PS_DLIST_CURRENT); 351 } 352 353 #if 0 320 354 /* 321 355 * Convert a psDlist to/from a psVoidPtrArray … … 356 390 return list; 357 391 } 392 393 #endif -
trunk/psLib/src/sysUtils/psDList.h
r455 r460 9 9 * @author Robert Daniel DeSonia, MHPCC 10 10 * 11 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-04- 19 21:06:37$11 * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-04-20 01:38:34 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 15 */ 16 16 17 /** Special values of index into list */ 18 enum { 19 PS_DLIST_HEAD = 0, ///< at head 20 PS_DLIST_TAIL = -1, ///< at tail 21 PS_DLIST_UNKNOWN = -2, ///< unknown position 22 PS_DLIST_PREVIOUS = -3, ///< previous element 23 PS_DLIST_CURRENT = -4, ///< current element 24 PS_DLIST_NEXT = -5 ///< next element 25 }; 26 17 27 /** Doubly-linked list element */ 18 28 typedef struct psDlistElem 19 29 { 20 struct psDlistElem *prev; ///< previous link in list21 struct psDlistElem *next; ///< next link in list22 void *data; ///< real data item30 struct psDlistElem *prev; ///< previous link in list 31 struct psDlistElem *next; ///< next link in list 32 void *data; ///< real data item 23 33 } 24 34 psDlistElem; … … 27 37 typedef struct 28 38 { 29 int n; ///< number of elements on list 30 psDlistElem *head; ///< first element on list (may be NULL) 31 psDlistElem *tail; ///< last element on list (may be NULL) 32 psDlistElem *iter; ///< iteration cursor 39 int n; ///< number of elements on list 40 psDlistElem *head; ///< first element on list (may be NULL) 41 psDlistElem *tail; ///< last element on list (may be NULL) 42 psDlistElem *iter; ///< iteration cursor 43 int iterIndex; 33 44 } 34 45 psDlist; 35 46 36 /** Special values of index into list */ 37 enum { 38 PS_DLIST_HEAD = 0, ///< at head 39 PS_DLIST_TAIL = -1, ///< at tail 40 PS_DLIST_UNKNOWN = -2, ///< unknown position 41 PS_DLIST_PREV = -3, ///< previous element 42 PS_DLIST_NEXT = -4 ///< next element 43 }; 44 45 /** Functions **************************************************************/ 46 /** \addtogroup DataGroup General Data Container Utilities 47 * \{ 47 /** @addtogroup DataContainers General Data Container Utilities 48 * @{ 48 49 */ 49 50 50 51 /** Constructor */ 51 psDlist *psDlistAlloc(void *data) ///< initial data item; may be NULL 52 ; 52 psDlist *psDlistAlloc( 53 void *data ///< initial data item; may be NULL 54 ); 53 55 54 56 /** Destructor */ 55 void psDlistFree(psDlist *list, ///< list to destroy 56 void (*elemFree)(void *)) ///< destructor for data on list 57 ; 58 59 /**** List maintainence functions ****/ 57 void psDlistFree( 58 psDlist *list, ///< list to destroy 59 void (*elemFree)(void *) ///< destructor for data on list 60 ); 60 61 61 62 /** Add to list */ 62 psDlist *psDlistAdd(psDlist *list, ///< list to add to (may be NULL) 63 void *data, ///< data item to add 64 int where) ///< index, PS_DLIST_HEAD, or PS_DLIST_TAIL 65 ; 63 psDlist *psDlistAdd( 64 psDlist *list, ///< list to add to (may be NULL) 65 void *data, ///< data item to add 66 int where ///< index, PS_DLIST_HEAD, or PS_DLIST_TAIL 67 ); 66 68 67 69 /** Append to a list */ 68 psDlist *psDlistAppend(psDlist *list, ///< list to append to (may be NULL) 69 void *data) ///< data item to add 70 ; 70 psDlist *psDlistAppend( 71 psDlist *list, ///< list to append to (may be NULL) 72 void *data ///< data item to add 73 ); 71 74 72 75 /** Remove from a list */ 73 void *psDlistRemove(psDlist *list, ///< list to remove element from 74 void *data, ///< data item to remove 75 int which) ///< index of item, or PS_DLIST_UNKNOWN, PS_DLIST_NEXT, PS_DLIST_PREV 76 ; 76 void *psDlistRemove( 77 psDlist *list, ///< list to remove element from 78 void *data, ///< data item to remove 79 int which ///< index of item, or PS_DLIST_UNKNOWN, PS_DLIST_NEXT, PS_DLIST_PREV 80 ); 77 81 78 82 /** Retrieve from a list */ 79 void *psDlistGet(const psDlist *list, ///< list to retrieve element from 80 int which) ///< index of item, or PS_DLIST_NEXT, PS_DLIST_PREV, PS_DLIST_UNKNOWN 81 ; 83 void *psDlistGet( 84 const psDlist *list, ///< list to retrieve element from 85 int which ///< index of item, or PS_DLIST_NEXT, PS_DLIST_PREV, PS_DLIST_UNKNOWN 86 ); 82 87 83 88 /** Set the iterator */ 84 void psDlistSetIterator(psDlist *list, ///< list to retrieve element from 85 int where) ///< index, PS_DLIST_HEAD, or PS_DLIST_TAIL 86 ; 89 void psDlistSetIterator( 90 psDlist *list, ///< list to retrieve element from 91 int where ///< index, PS_DLIST_HEAD, or PS_DLIST_TAIL 92 ); 87 93 88 94 /** Get next element relative to iter */ 89 void *psDlistGetNext(psDlist *list) ///< list to retrieve element from 90 ; 95 void *psDlistGetNext( 96 psDlist *list ///< list to retrieve element from 97 ); 98 99 /** Get current element at iter */ 100 void *psDlistGetCurrent( 101 psDlist *list ///< list to retrieve element from 102 ); 91 103 92 104 /** Get prev element relative to iter */ 93 void *psDlistGetPrev(psDlist *list) ///< list to retrieve element from 94 ; 105 void *psDlistGetPrevious( 106 psDlist *list ///< list to retrieve element from 107 ); 95 108 96 109 /** Convert doubly-linked list to an array */ 97 psVoidPtrArray *psDlistToArray(psDlist *dlist) ///< List to convert 98 ; 110 #if 0 111 psVoidPtrArray *psDlistToArray( 112 psDlist *dlist ///< List to convert 113 ); 99 114 100 115 /** Convert array to a doubly-linked list */ 101 psDlist *psArrayToDlist(psVoidPtrArray *arr) ///< Array to convert 102 ; 116 psDlist *psArrayToDlist( 117 psVoidPtrArray *arr ///< Array to convert 118 ); 119 #endif 103 120 104 / * \} */ //End of DataGroup Functions121 /// @} End of DataGroup Functions 105 122 106 123 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
