source: trunk/libtransmission/list.c @ 2846

Last change on this file since 2846 was 2846, checked in by charles, 14 years ago

$Id$

File size: 2.8 KB
Line 
1/*
2 * This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id$
11 */
12
13#include "transmission.h"
14#include "list.h"
15#include "utils.h"
16
17static tr_list_t*
18node_alloc( void )
19{
20    return tr_new0( tr_list_t, 1 );
21}
22
23static void
24node_free( tr_list_t* node )
25{
26    tr_free( node );
27}
28
29/***
30****
31***/
32
33void
34tr_list_free( tr_list_t** list )
35{
36    while( *list )
37    {
38        tr_list_t * node = *list;
39        *list = (*list)->next;
40        node_free( node );
41    }
42}
43
44void
45tr_list_prepend( tr_list_t ** list, void * data )
46{
47    tr_list_t * node = node_alloc ();
48    node->data = data;
49    node->next = *list;
50    if( *list )
51        (*list)->prev = node;
52    *list = node;
53}
54
55void
56tr_list_append( tr_list_t ** list, void * data )
57{
58    tr_list_t * node = node_alloc( );
59    node->data = data;
60    if( !*list )
61        *list = node;
62    else {
63        tr_list_t * l = *list;
64        while( l->next )
65            l = l->next;
66        l->next = node;
67        node->prev = l;
68    }
69}
70
71void
72tr_list_insert_sorted( tr_list_t ** list,
73                       void       * data,
74                       int          compare(const void*,const void*) )
75{
76    /* find l, the node that we'll insert this data before */
77    tr_list_t * l;
78    for( l=*list; l!=NULL; l=l->next ) {
79        const int c = (compare)( data, l->data );
80        if( c <= 0 )
81            break;
82    }
83
84    if( l == NULL)
85        tr_list_append( list, data );
86    else if( l == *list )
87        tr_list_prepend( list, data );
88    else {
89        tr_list_t * node = node_alloc( );
90        node->data = data;
91        if( l->prev ) { node->prev = l->prev; node->prev->next = node; }
92        node->next = l;
93        l->prev = node;
94    }
95}
96
97
98tr_list_t*
99tr_list_find_data ( tr_list_t * list, const void * data )
100{
101    for(; list; list=list->next )
102        if( list->data == data )
103            return list;
104
105    return NULL;
106}
107
108void
109tr_list_remove_data ( tr_list_t ** list, const void * data )
110{
111    tr_list_t * node = tr_list_find_data( *list, data );
112    tr_list_t * prev = node ? node->prev : NULL;
113    tr_list_t * next = node ? node->next : NULL;
114    if( prev ) prev->next = next;
115    if( next ) next->prev = prev;
116    if( *list == node ) *list = next;
117    node_free( node );
118}
119
120tr_list_t*
121tr_list_find ( tr_list_t * list , const void * b, TrListCompareFunc func )
122{
123    for( ; list; list=list->next )
124        if( !func( list->data, b ) )
125            return list;
126
127    return NULL;
128}
129
130void
131tr_list_foreach( tr_list_t * list, TrListForeachFunc func )
132{
133    while( list )
134    {
135        func( list->data );
136        list = list->next;
137    }
138}
Note: See TracBrowser for help on using the repository browser.