Changeset 460 for trunk/psLib/src/sysUtils/psDList.c
- Timestamp:
- Apr 19, 2004, 3:38:34 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/sysUtils/psDList.c (modified) (16 diffs)
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
Note:
See TracChangeset
for help on using the changeset viewer.
