Line data Source code
1 : /* This file is part of GNU cflow
2 : Copyright (C) 1997, 2005, 2006, 2007, 2009, 2010 Sergey Poznyakoff
3 :
4 : GNU cflow is free software; you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation; either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : GNU cflow is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public
15 : License along with GNU cflow; if not, write to the Free Software
16 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 : MA 02110-1301 USA */
18 :
19 : #include <cflow.h>
20 :
21 : static struct linked_list *
22 108028 : deref_linked_list (struct linked_list **plist)
23 : {
24 108028 : if (!*plist) {
25 14796 : struct linked_list *list = xmalloc(sizeof(*list));
26 14796 : list->free_data = NULL;
27 14796 : list->head = list->tail = NULL;
28 14796 : *plist = list;
29 : }
30 108028 : return *plist;
31 : }
32 :
33 :
34 : struct linked_list *
35 9661 : linked_list_create(linked_list_free_data_fp fun)
36 : {
37 9661 : struct linked_list *list = xmalloc(sizeof(*list));
38 9661 : list->free_data = fun;
39 9661 : list->head = list->tail = NULL;
40 9661 : return list;
41 : }
42 :
43 : void
44 108028 : linked_list_append(struct linked_list **plist, void *data)
45 : {
46 108028 : struct linked_list *list = deref_linked_list (plist);
47 108028 : struct linked_list_entry *entry = xmalloc(sizeof(*entry));
48 :
49 108028 : entry->list = list;
50 108028 : entry->data = data;
51 108028 : entry->next = NULL;
52 108028 : entry->prev = list->tail;
53 108028 : if (list->tail)
54 83571 : list->tail->next = entry;
55 : else
56 24457 : list->head = entry;
57 108028 : list->tail = entry;
58 108028 : }
59 :
60 : #if 0
61 : void
62 : linked_list_prepend(struct linked_list **plist, void *data)
63 : {
64 : struct linked_list *list = deref_linked_list (plist);
65 : struct linked_list_entry *entry = xmalloc(sizeof(*entry));
66 :
67 : entry->list = list;
68 : entry->data = data;
69 : if (list->head)
70 : list->head->prev = entry;
71 : entry->next = list->head;
72 : entry->prev = NULL;
73 : list->head = entry;
74 : if (!list->tail)
75 : list->tail = entry;
76 : }
77 : #endif
78 :
79 : void
80 25692 : linked_list_destroy(struct linked_list **plist)
81 : {
82 25692 : if (plist && *plist) {
83 3158 : struct linked_list *list = *plist;
84 : struct linked_list_entry *p;
85 :
86 9645 : for (p = list->head; p; ) {
87 3329 : struct linked_list_entry *next = p->next;
88 3329 : if (list->free_data)
89 3009 : list->free_data(p->data);
90 3329 : free(p);
91 3329 : p = next;
92 : }
93 3158 : free(list);
94 3158 : *plist = NULL;
95 : }
96 25692 : }
97 :
98 : void
99 7360 : linked_list_unlink(struct linked_list *list, struct linked_list_entry *ent)
100 : {
101 : struct linked_list_entry *p;
102 :
103 7360 : if ((p = ent->prev))
104 830 : p->next = ent->next;
105 : else
106 6530 : list->head = ent->next;
107 :
108 7360 : if ((p = ent->next))
109 3822 : p->prev = ent->prev;
110 : else
111 3538 : list->tail = ent->prev;
112 7360 : if (list->free_data)
113 0 : list->free_data(ent->data);
114 7360 : free(ent);
115 7360 : }
116 :
117 : void
118 28656 : linked_list_iterate(struct linked_list **plist,
119 : int (*itr) (void *, void *), void *data)
120 : {
121 : struct linked_list *list;
122 : struct linked_list_entry *p;
123 :
124 28656 : if (!*plist)
125 37456 : return;
126 19856 : list = *plist;
127 279157 : for (p = linked_list_head(list); p; ) {
128 239445 : struct linked_list_entry *next = p->next;
129 :
130 239445 : if (itr(p->data, data))
131 7248 : linked_list_unlink(list, p);
132 239445 : p = next;
133 : }
134 19856 : if (!list->head)
135 2901 : linked_list_destroy(&list);
136 19856 : *plist = list;
137 : }
138 :
139 : int
140 92123 : data_in_list(void *data, struct linked_list *list)
141 : {
142 : struct linked_list_entry *p;
143 :
144 631427 : for (p = linked_list_head(list); p; p = p->next)
145 576956 : if (p->data == data)
146 37652 : return 1;
147 54471 : return 0;
148 : }
|