/src/libplist/libcnary/node_list.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * node_list.c |
3 | | * |
4 | | * Created on: Mar 8, 2011 |
5 | | * Author: posixninja |
6 | | * |
7 | | * Copyright (c) 2011 Joshua Hill. All Rights Reserved. |
8 | | * |
9 | | * This library is free software; you can redistribute it and/or |
10 | | * modify it under the terms of the GNU Lesser General Public |
11 | | * License as published by the Free Software Foundation; either |
12 | | * version 2.1 of the License, or (at your option) any later version. |
13 | | * |
14 | | * This library is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | | * Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public |
20 | | * License along with this library; if not, write to the Free Software |
21 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | | */ |
23 | | |
24 | | #include <stdio.h> |
25 | | #include <stdlib.h> |
26 | | #include <string.h> |
27 | | |
28 | | #include "node.h" |
29 | | #include "node_list.h" |
30 | | |
31 | | void node_list_destroy(node_list_t list) |
32 | 537k | { |
33 | 537k | free(list); |
34 | 537k | } |
35 | | |
36 | | node_list_t node_list_create() |
37 | 34.7k | { |
38 | 34.7k | node_list_t list = (node_list_t)calloc(1, sizeof(struct node_list)); |
39 | 34.7k | if (list == NULL) { |
40 | 0 | return NULL; |
41 | 0 | } |
42 | | |
43 | | // Initialize structure |
44 | 34.7k | list->begin = NULL; |
45 | 34.7k | list->end = NULL; |
46 | 34.7k | list->count = 0; |
47 | 34.7k | return list; |
48 | 34.7k | } |
49 | | |
50 | | int node_list_add(node_list_t list, node_t node) |
51 | 408k | { |
52 | 408k | if (!list || !node) return -1; |
53 | | |
54 | | // Find the last element in the list |
55 | 408k | node_t last = list->end; |
56 | | |
57 | | // Setup our new node as the new last element |
58 | 408k | node->next = NULL; |
59 | 408k | node->prev = last; |
60 | | |
61 | | // Set the next element of our old "last" element |
62 | 408k | if (last) { |
63 | | // but only if the node list is not empty |
64 | 373k | last->next = node; |
65 | 373k | } else { |
66 | | // otherwise this is the start of the list |
67 | 34.7k | list->begin = node; |
68 | 34.7k | } |
69 | | |
70 | | // Set the lists prev to the new last element |
71 | 408k | list->end = node; |
72 | | |
73 | | // Increment our node count for this list |
74 | 408k | list->count++; |
75 | 408k | return 0; |
76 | 408k | } |
77 | | |
78 | | int node_list_insert(node_list_t list, unsigned int node_index, node_t node) |
79 | 7.82k | { |
80 | 7.82k | if (!list || !node) return -1; |
81 | 7.82k | if (node_index >= list->count) { |
82 | 5.11k | return node_list_add(list, node); |
83 | 5.11k | } |
84 | | |
85 | | // Get the first element in the list |
86 | 2.70k | node_t cur = list->begin; |
87 | | |
88 | 2.70k | unsigned int pos = 0; |
89 | 2.70k | node_t prev = NULL; |
90 | | |
91 | 2.70k | if (node_index > 0) { |
92 | 315k | while (pos < node_index) { |
93 | 312k | prev = cur; |
94 | 312k | cur = cur->next; |
95 | 312k | pos++; |
96 | 312k | } |
97 | 2.70k | } |
98 | | |
99 | 2.70k | if (prev) { |
100 | | // Set previous node |
101 | 2.70k | node->prev = prev; |
102 | | // Set next node of our new node to next node of the previous node |
103 | 2.70k | node->next = prev->next; |
104 | | // Set next node of previous node to our new node |
105 | 2.70k | prev->next = node; |
106 | 2.70k | } else { |
107 | 0 | node->prev = NULL; |
108 | | // get old first element in list |
109 | 0 | node->next = list->begin; |
110 | | // set new node as first element in list |
111 | 0 | list->begin = node; |
112 | 0 | } |
113 | | |
114 | 2.70k | if (node->next == NULL) { |
115 | | // Set the lists prev to the new last element |
116 | 0 | list->end = node; |
117 | 2.70k | } else { |
118 | | // set prev of the new next element to our node |
119 | 2.70k | node->next->prev = node; |
120 | 2.70k | } |
121 | | |
122 | | // Increment our node count for this list |
123 | 2.70k | list->count++; |
124 | 2.70k | return 0; |
125 | 7.82k | } |
126 | | |
127 | | int node_list_remove(node_list_t list, node_t node) |
128 | 411k | { |
129 | 411k | if (!list || !node) return -1; |
130 | 411k | if (list->count == 0) return -1; |
131 | | |
132 | 411k | int node_index = 0; |
133 | 411k | node_t n; |
134 | 756k | for (n = list->begin; n; n = n->next) { |
135 | 756k | if (node == n) { |
136 | 411k | node_t newnode = node->next; |
137 | 411k | if (node->prev) { |
138 | 7.82k | node->prev->next = newnode; |
139 | 7.82k | if (newnode) { |
140 | 2.70k | newnode->prev = node->prev; |
141 | 5.11k | } else { |
142 | | // last element in the list |
143 | 5.11k | list->end = node->prev; |
144 | 5.11k | } |
145 | 403k | } else { |
146 | | // we just removed the first element |
147 | 403k | if (newnode) { |
148 | 368k | newnode->prev = NULL; |
149 | 368k | } else { |
150 | 34.7k | list->end = NULL; |
151 | 34.7k | } |
152 | 403k | list->begin = newnode; |
153 | 403k | } |
154 | 411k | list->count--; |
155 | 411k | return node_index; |
156 | 411k | } |
157 | 345k | node_index++; |
158 | 345k | } |
159 | 0 | return -1; |
160 | 411k | } |