1 /*
2 * list.c
3 *
4 * Copyright (c) 2002-2005 by Judd Vinet <jvinet@zeroflux.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
20 */
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include "list.h"
26
list_new()27 PMList* list_new()
28 {
29 PMList *list = NULL;
30
31 list = (PMList*)malloc(sizeof(PMList));
32 if(list == NULL) {
33 return(NULL);
34 }
35 list->data = NULL;
36 list->prev = NULL;
37 list->next = NULL;
38 return(list);
39 }
40
list_free(PMList * list)41 void list_free(PMList *list)
42 {
43 if(list == NULL) {
44 return;
45 }
46 if(list->data != NULL) {
47 free(list->data);
48 list->data = NULL;
49 }
50 if(list->next != NULL) {
51 list_free(list->next);
52 }
53 free(list);
54 return;
55 }
56
list_add(PMList * list,void * data)57 PMList* list_add(PMList *list, void *data)
58 {
59 PMList *ptr, *lp;
60
61 ptr = list;
62 if(ptr == NULL) {
63 ptr = list_new();
64 }
65
66 lp = list_last(ptr);
67 if(lp == ptr && lp->data == NULL) {
68 /* nada */
69 } else {
70 lp->next = list_new();
71 if(lp->next == NULL) {
72 return(NULL);
73 }
74 lp->next->prev = lp;
75 lp = lp->next;
76 }
77 lp->data = data;
78 return(ptr);
79 }
80
list_remove(PMList * list,void * data)81 PMList* list_remove(PMList* list, void* data)
82 {
83 PMList *ptr, *lp;
84
85 ptr = list;
86
87 for(lp = list; lp; lp = lp->next) {
88 if(lp->data == data) {
89 if(lp->prev != NULL) {
90 lp->prev->next = lp->next;
91 }
92 if(lp->next != NULL) {
93 lp->next->prev = lp->prev;
94 }
95 /* test if we just removed the head */
96 if(lp == ptr) {
97 ptr = lp->next;
98 }
99 }
100 }
101 return ptr;
102 }
103
list_count(PMList * list)104 int list_count(PMList *list)
105 {
106 int i;
107 PMList *lp;
108
109 for(lp = list, i = 0; lp; lp = lp->next, i++);
110 return(i);
111 }
112
list_isin(PMList * haystack,void * needle)113 int list_isin(PMList *haystack, void *needle)
114 {
115 PMList *lp;
116
117 for(lp = haystack; lp; lp = lp->next) {
118 if(lp->data == needle) {
119 return(1);
120 }
121 }
122 return(0);
123 }
124
125 /* Test for existence of a string in a PMList
126 */
is_in(char * needle,PMList * haystack)127 int is_in(char *needle, PMList *haystack)
128 {
129 PMList *lp;
130
131 for(lp = haystack; lp; lp = lp->next) {
132 if(lp->data && !strcmp(lp->data, needle)) {
133 return(1);
134 }
135 }
136 return(0);
137 }
138
139 /* List one is extended and returned
140 */
list_merge(PMList * one,PMList * two)141 PMList* list_merge(PMList *one, PMList *two)
142 {
143 PMList *lp, *ptr;
144
145 if(two == NULL) {
146 return one;
147 }
148
149 ptr = one;
150 if(ptr == NULL) {
151 ptr = list_new();
152 }
153
154 for(lp = two; lp; lp = lp->next) {
155 if(lp->data) {
156 ptr = list_add(ptr, lp->data);
157 lp->data = NULL;
158 }
159 }
160
161 return(ptr);
162 }
163
list_last(PMList * list)164 PMList* list_last(PMList *list)
165 {
166 PMList *ptr;
167
168 for(ptr = list; ptr && ptr->next; ptr = ptr->next);
169 return(ptr);
170 }
171
172 /* Helper function for sorting a list of strings
173 */
list_strcmp(const void * s1,const void * s2)174 int list_strcmp(const void *s1, const void *s2)
175 {
176 char **str1 = (char **)s1;
177 char **str2 = (char **)s2;
178
179 return(strcmp(*str1, *str2));
180 }
181
list_sort(PMList * list)182 PMList *list_sort(PMList *list)
183 {
184 char **arr = NULL;
185 PMList *lp;
186 unsigned int arrct;
187 int i;
188
189 if(list == NULL) {
190 return(NULL);
191 }
192
193 arrct = list_count(list);
194 arr = (char **)malloc(arrct*sizeof(char*));
195 for(lp = list, i = 0; lp; lp = lp->next) {
196 arr[i++] = (char *)lp->data;
197 }
198
199 qsort(arr, (size_t)arrct, sizeof(char *), list_strcmp);
200
201 lp = NULL;
202 for(i = 0; i < arrct; i++) {
203 lp = list_add(lp, strdup(arr[i]));
204 }
205
206 if(arr) {
207 free(arr);
208 arr = NULL;
209 }
210
211 return(lp);
212 }
213
list_display(const char * title,PMList * list)214 void list_display(const char *title, PMList *list)
215 {
216 PMList *lp;
217 int cols, len, maxcols = 80;
218 char *cenv = NULL;
219
220 cenv = getenv("COLUMNS");
221 if(cenv) {
222 maxcols = atoi(cenv);
223 }
224
225 len = strlen(title);
226 printf("%s ", title);
227
228 if(list) {
229 for(lp = list, cols = len; lp; lp = lp->next) {
230 int s = strlen((char*)lp->data)+1;
231 if(s+cols >= maxcols) {
232 int i;
233 cols = len;
234 printf("\n");
235 for (i = 0; i < len+1; i++) {
236 printf(" ");
237 }
238 }
239 printf("%s ", (char*)lp->data);
240 cols += s;
241 }
242 printf("\n");
243 } else {
244 printf("None\n");
245 }
246 }
247
248 /* vim: set ts=2 sw=2 noet: */
249