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