~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Tina5/tina-libs/tina/sys/sysLst_dd.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /**********
  2  * 
  3  * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
  4  * University of Manchester, UK.  All rights reserved.
  5  * 
  6  * Redistribution and use in source and binary forms, with or without modification, 
  7  * are permitted provided that the following conditions are met:
  8  * 
  9  *   . Redistributions of source code must retain the above copyright notice, 
 10  *     this list of conditions and the following disclaimer.
 11  *    
 12  *   . Redistributions in binary form must reproduce the above copyright notice,
 13  *     this list of conditions and the following disclaimer in the documentation 
 14  *     and/or other materials provided with the distribution.
 15  * 
 16  *   . Neither the name of the University of Manchester nor the names of its
 17  *     contributors may be used to endorse or promote products derived from this 
 18  *     software without specific prior written permission.
 19  * 
 20  * 
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  *
 33  **********
 34  * 
 35  * Program :    TINA
 36  * File    :  $Source: /home/tina/cvs/tina-libs/tina/sys/sysLst_dd.c,v $
 37  * Date    :  $Date: 2008/10/02 11:53:05 $
 38  * Version :  $Revision: 1.8 $
 39  * CVS Id  :  $Id: sysLst_dd.c,v 1.8 2008/10/02 11:53:05 neil Exp $
 40  *
 41  * Notes :
 42  *
 43  *  List (doubly directed lists) handling.
 44  *  List is { int type; List *next; List *last; void *to; }
 45  *
 46  *********
 47 */
 48 
 49 #include "sysLst_dd.h"
 50 
 51 #if HAVE_CONFIG_H
 52   #include <config.h>
 53 #endif
 54 
 55 #include <stdio.h>
 56 
 57 #if HAVE_STDARG_H
 58 #  include <stdarg.h>
 59 #  define VA_START(a, f)                va_start(a, f)
 60 #else
 61 #  if HAVE_VARARGS_H
 62 #    include <varargs.h>
 63 #    define VA_START(a, f)  va_start(a)
 64 #  endif
 65 #endif /* HAVE_STDARG_H */
 66 #ifndef VA_START
 67   error no variadic api available
 68 #endif
 69 
 70 #include <tina/sys/sys_GenDef.h>
 71 #include <tina/sys/sys_LstDef.h>
 72 #include <tina/sys/sys_MemDef.h>
 73 #include <tina/sys/sysMem_ralloc.h>
 74 #include <tina/sys/sysGen_error.h>
 75 
 76 
 77 /* Allocate space and set a single list element */
 78 List *dd_link_alloc(void *ptr, int type)
 79 {
 80         List *list;
 81 
 82         list = ts_ralloc(List);
 83         list->next = NULL;
 84         list->type = type;
 85         list->last = NULL;
 86         list->to = ptr;
 87         return (list);
 88 }
 89 
 90 void dd_ref_set(List * el, void *ptr, int type)
 91 {
 92         el->to = ptr;
 93         el->type = type;
 94 }
 95 
 96 List *dd_list_make(int n, int type)     /* make and initialize a list
 97                                                                                                                                                  * * of length n */
 98 {
 99         int i;
100         List *list = NULL;
101         List *dd_ref_addtostart(List * list, void *ptr, int type);
102 
103         for (i = 0; i < n; i++)
104                 list = dd_ref_addtostart(list, NULL, type);
105 
106         return (list);
107 }
108 
109 List *dd_get_end(List * list)
110 {
111         if (list == NULL)
112                 return (NULL);
113 
114         while (list->next != NULL)
115                 list = list->next;
116 
117         return (list);
118 }
119 
120 List *dd_get_start(List * list)
121 {
122         if (list == NULL)
123                 return (NULL);
124 
125         while (list->last != NULL)
126                 list = list->last;
127 
128         return (list);
129 }
130 
131 List *dd_append(List * l1, List * l2)   /* append l2 to l1 */
132 {
133         List *lptr;
134 
135         if (l1 == NULL)
136                 return (l2);
137 
138         if (l2 == NULL)
139                 return (l1);
140 
141         for (lptr = l1; lptr->next != NULL; lptr = lptr->next);
142 
143         lptr->next = l2;
144         l2->last = lptr;
145 
146         return (l1);
147 }
148 
149 /* Add new element to front of list returning front of list */
150 List *dd_link_addtostart(List * list, List * el)
151 {
152         if (el == NULL)
153                 return (list);
154 
155         el->next = list;
156         el->last = NULL;
157         if (list != NULL)
158                 list->last = el;
159         return (el);
160 }
161 
162 List *dd_ref_addtostart(List * list, void *ptr, int type)
163 {
164         return (dd_link_addtostart(list, dd_link_alloc(ptr, type)));
165 }
166 
167 List *dd_link_addtoend(List * end, List * el)   
168 /* add new element to
169  * * back of list
170  * * returning back of
171  * * list */
172 {
173         if (el == NULL)
174                 return (end);
175 
176         el->next = NULL;
177         el->last = end;
178         if (end != NULL)
179                 end->next = el;
180         return (el);
181 }
182 
183 List *dd_ref_addtoend(List * end, void *ptr, int type)
184 {
185         return (dd_link_addtoend(end, dd_link_alloc(ptr, type)));
186 }
187 
188 List *dd_list_addtoend(List * list, List * el)  
189 /* add new element to
190  * * back of list
191  * * returning front of
192  * * list */
193 {
194         List *end;
195 
196         if (el == NULL)
197                 return (list);
198 
199         end = dd_get_end(list);
200         el->next = NULL;
201         el->last = end;
202         if (list == NULL)
203                 return (el);
204 
205         end->next = el;
206         return (list);
207 }
208 
209 void dd_link_addafter(List * at, List * el)     
210 /* add new element after
211 * * at */
212 {
213         if (at == NULL || el == NULL)
214                 return;
215 
216         el->next = at->next;
217         at->next = el;
218         el->last = at;
219         if (el->next != NULL)
220                 el->next->last = el;
221 }
222 
223 void dd_link_rm_next_el(List * at) /* rm next element from list */
224 {
225         List *temp;
226 
227         if (at == NULL || at->next == NULL)
228                 return;
229 
230         temp = at->next;
231         at->next = at->next->next;
232         if (at->next != NULL)
233                 at->next->last = at;
234         rfree((void *) temp);
235 }
236 
237 List *dd_link_rm_el(List * at)  /* rm element returning next */
238 {
239         List *next;
240 
241         if (at == NULL)
242                 return (NULL);
243 
244         next = at->next;
245 
246         if (at->next != NULL)
247                 at->next->last = at->last;
248 
249         if (at->last != NULL)
250                 at->last->next = at->next;
251 
252         rfree((void *) at);
253         return (next);
254 }
255 
256 void dd_ref_free(List * at, void (*freefunc) ( /* ??? */ ))     /* free element at */
257 {
258         if (at == NULL || freefunc == NULL)
259                 return;
260 
261         freefunc(at->to, at->type);
262         at->to = NULL;
263 }
264 
265 void dd_link_rm_next(List * at, void (*freefunc) ( /* ??? */ )) /* free and rm next
266                                                                                                                                                                                                                                                                  * * element */
267 {
268         if (at == NULL)
269                 return;
270 
271         dd_ref_free(at->next, freefunc);
272         (void) dd_link_rm_next_el(at);
273 }
274 
275 /* Free and rm this element returning next */
276 List *dd_link_rm(List * at, void (*freefunc) ( /* ??? */ ))
277 {
278         if (at == NULL)
279                 return (NULL);
280 
281         dd_ref_free(at, freefunc);
282         return (dd_link_rm_el(at));
283 }
284 
285 List *dd_list_rm_el(List * list, List * el, void (*freefunc) ( /* ??? */ ))
286 {
287         List *previous=NULL;
288         List *next=NULL;
289         List *ptr;
290 
291 /* check sanity of list structure before freeing NAT 21/2/2007 */
292 /* assume that at least ->next data is correct and attempt fix */
293         for (ptr = list; ptr !=NULL; ptr= ptr->next)
294         {
295              next = ptr->next;
296              if (ptr == el) break;
297              previous = ptr;
298         }
299         if (el &&(el->last != previous))
300         {
301             error("dd_list_rm_el: fixing inconsistent list, DEBUG HERE (1)", non_fatal);
302             el->last = previous;
303         }
304         if (next && (next->last != el))
305         {
306             error("dd_list_rm_el: fixing inconsistent list, DEBUG HERE (2)", non_fatal);
307             next->last = el;
308         }
309         if (previous && (previous->next != el))
310         {
311             error("dd_list_rm_el: fixing inconsistent list, DEBUG HERE (3)", non_fatal);
312             previous->next = el;
313         }
314 
315         if (list == NULL)
316                 return (NULL);
317 
318         if (el == list)
319                 return (dd_link_rm(el, freefunc));      /* was memory leak NAT 7/2/2002 */
320 
321         (void) dd_link_rm(el, freefunc);        /* actually removes element * * from list */
322         return (list);
323 }
324 
325 List *dd_link_get_by_ref(List * list, void *ptr)        /* get list element by
326                                                                                                                                                                                                          * * reference */
327 {
328         List *lptr;
329 
330         for (lptr = list; lptr != NULL; lptr = lptr->next)
331                 if (lptr->to == ptr)
332                         return (lptr);
333 
334         return (NULL);
335 }
336 
337 List *dd_link_get_by_type(List * list, int type)        /* get next list
338                                                                                                                                                                                                          * * element of type */
339 {
340         List *lptr;
341 
342         for (lptr = list; lptr != NULL; lptr = lptr->next)
343                 if (lptr->type == type)
344                         return (lptr);
345 
346         return (NULL);
347 }
348 
349 List *dd_list_rm_ref(List * list, void *ptr, void (*freefunc) ( /* ??? */ ))
350 {
351         List *el;
352 
353         if (list == NULL)
354                 return (NULL);
355 
356         el = dd_link_get_by_ref(list, ptr);
357         if (el == NULL)
358                 return (NULL);
359         return (dd_list_rm_el(list, el, freefunc));
360 }
361 
362 void dd_list_rm_links(List * list) /* remove a list */
363 {
364         while (list != NULL)
365                 list = dd_link_rm_el(list);
366 }
367 
368 List *dd_list_rm_links_on_type(List * list, int type)
369 {
370 
371   /*mjs modified 24/7/03 - logical fault in while loop, as it could remove all elements
372     giving a null list, which is then passed into the for loop */
373         List *lptr;
374 
375         while (list != NULL && list->type == type)
376           list = dd_link_rm_el(list);
377 
378         if (list == NULL)
379           return(list);
380 
381         if (list == NULL)
382                 return NULL;
383 
384         for (lptr = list->next; lptr != NULL;)
385           if (lptr->type == type)
386             lptr = dd_link_rm_el(lptr); /* bug found NAT 7/02/2002 */
387           else
388             lptr = lptr->next;
389         
390         /*list = dd_get_start(lptr);*/
391 
392         return (list);
393 }
394 
395 List *dd_list_rm_links_on_func(List * list, Bool(*func) ( /* ??? */ ),
396                                                                                                                          void *data)
397 {
398         List *lptr;
399 
400         while (list != NULL && func(list->to, list->type, data) == true)
401                 list = dd_link_rm_el(list);
402 
403         if (list == NULL) return(NULL);
404 
405         for (lptr = list->next; lptr != NULL;)
406                 if (func(lptr->to, lptr->type, data) == true)
407                         lptr = dd_link_rm_el(lptr);
408                 else
409                         lptr = lptr->next;
410 
411         return (list);
412 }
413 
414 void dd_list_free_refs(List * list, void (*freefunc) ( /* ??? */ ))
415 /* free the elements of  a list */
416 {
417         List *lptr;
418 
419         for (lptr = list; lptr != NULL; lptr = lptr->next)
420                 dd_ref_free(lptr, freefunc);
421 }
422 
423 /* Free and rm the elements of a list */
424 void dd_list_rm(List * list, void (*freefunc) ( /* ??? */ ))
425 {
426         while (list != NULL)
427                 list = dd_link_rm(list, freefunc);
428 }
429 
430 List *dd_link_copy(List * el, void *(*cpfunc) ( /* ??? */ ), void *data)
431 {
432         void *cpy;
433 
434         if (cpfunc == NULL)
435                 return (dd_link_alloc(el->to, el->type));
436         cpy = cpfunc(el->to, el->type, data);
437         return ((cpy == NULL) ? NULL : dd_link_alloc(cpy, el->type));
438 }
439 
440 List *dd_list_copy(List * list, void *(*cpfunc) ( /* ??? */ ), void *data)      /* copy a whole list */
441 {
442         List *copy;
443         List *end;
444         List *lptr;
445 
446         copy = NULL;
447 
448         if (list == NULL)
449                 return (NULL);
450 
451         for (end = NULL, lptr = list; end == NULL && lptr != NULL;
452                          lptr = lptr->next)
453                 end = copy = dd_link_copy((List *) lptr, cpfunc, data); /* bug found NAT 7/02/2002 */
454 
455         for (; lptr != NULL; lptr = lptr->next)
456                 end = dd_link_addtoend(end, dd_link_copy((List *) lptr, cpfunc, data));
457         return (copy);
458 }
459 
460 List *dd_list_reverse(List * list)      /* reverse a list without
461                                                                                                                                                  * * copying it */
462 {
463         List *rev = NULL;
464 
465         while (list)
466         {
467                 List *next;
468 
469                 next = list->next;
470                 rev = dd_link_addtostart(rev, list);
471                 list = next;
472         }
473         return (rev);
474 }
475 
476 List *dd_list_reversecopy(List * list, void *(*cpfunc) ( /* ??? */ ), void *data)
477 /* bug found in prototype NAT 7/2/2202 */
478 {
479         List *rev = NULL;
480         List *lptr;
481 
482         for (lptr = list; lptr != NULL; lptr = lptr->next)
483                 rev = dd_link_addtostart(rev, dd_link_copy((List *) lptr->to, 
484                                          (void *(*)()) cpfunc, data));
485 
486         return (rev);
487 }
488 
489 void dd_apply_func(List * list, void (*func) ( /* ??? */ ), void *data)
490 {
491         List *lptr;
492 
493         for (lptr = list; lptr != NULL; lptr = lptr->next)
494                 func(lptr->to, lptr->type, data);
495 }
496 
497 List *dd_get_min(List * list, Bool(*func) ( /* ??? */ ), void *data)
498 {
499         List *lptr;
500         List *min_ptr = NULL;
501         double min_d = 0.0;
502         double d;
503 
504         for (lptr = list; lptr != NULL; lptr = lptr->next)
505         {
506                 if (func(lptr->to, lptr->type, data, &d) == true &&
507                                 (min_ptr == NULL || d < min_d))
508                 {
509                         min_ptr = lptr;
510                         min_d = d;
511                 }
512         }
513         return (min_ptr);
514 }
515 
516 List *dd_list_add_sorted(List * list, List * el,
517                                                                                                  double (*sortfunc) ( /* ??? */ ))
518 {
519         double val;
520         List *lptr;
521 
522         if (el == NULL)
523                 return (list);
524         if (list == NULL)
525         {
526                 el->next = NULL;
527                 return (el);
528         }
529         val = sortfunc(el->to, el->type);
530 
531         if (val < sortfunc(list->to, list->type))
532                 return (dd_link_addtostart(list, el));
533 
534         for (lptr = list; lptr->next != NULL; lptr = lptr->next)
535                 if (val < sortfunc(lptr->next->to, lptr->next->type))
536                         break;
537 
538         dd_link_addafter(lptr, el);
539         return (list);
540 }
541 
542 List *dd_nth_el(List * list, int n)
543 {
544         int i;
545 
546         for (i = 0; i < n; ++i, list = list->next)
547                 if (list == NULL)
548                         return (NULL);
549 
550         return (list);
551 }
552 
553 void *dd_list_query(List * list, void *(*match_func) ( /* ??? */ ),
554                                                                                 void *key)
555 {
556         void *data;
557 
558         for (data = NULL;
559                          list && !(data = match_func(key, list->to)); list = list->next);
560 
561         return data;
562 }
563 
564 List 
565 #if HAVE_STDARG_H
566 *dd_list_of(int type, ...)
567 #else
568 *dd_list_of(type, va_alist)
569         int type;
570         va_dcl
571 #endif /* HAVE_STDARG_H */
572 {
573 /* old code NAT 7/2/2002
574     va_list ap;
575     List *list = NULL;
576 
577     va_start(ap, ptr);
578 
579     while (ptr)
580     {
581         int     type = va_arg(ap, int);
582 
583         list = dd_ref_addtostart(list, ptr, type);
584         ptr = va_arg(ap, void *);
585 
586     }
587     va_end(ap);
588     return (dd_list_reverse(list));
589 */
590         va_list ap;
591         List *list = NULL;
592 
593         VA_START(ap, type);
594 
595         while (type)
596         {
597                 void *ptr = va_arg(ap, void *);
598 
599                 list = dd_ref_addtostart(list, ptr, type);
600                 type = va_arg(ap, int);
601         }
602         va_end(ap);
603         return (dd_list_reverse(list));
604 }
605 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.