Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/source/list.c
1069 views
1
/*
2
* list.c: some generic linked list managing stuff
3
*
4
* Written By Michael Sandrof
5
*
6
* Copyright(c) 1990
7
*
8
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
9
*/
10
11
12
#include "irc.h"
13
static char cvsrevision[] = "$Id: list.c 3 2008-02-25 09:49:14Z keaston $";
14
CVS_REVISION(list_c)
15
#include "struct.h"
16
17
#include "list.h"
18
19
#include "ircaux.h"
20
#define MAIN_SOURCE
21
#include "modval.h"
22
23
static int add_list_stricmp (List *, List *);
24
static int list_stricmp (List *, char *);
25
static int list_match (List *, char *);
26
27
/*
28
* These have now been made more general. You used to only be able to
29
* order these lists by alphabetical order. You can now order them
30
* arbitrarily. The functions are still called the same way if you
31
* wish to use alphabetical order on the key string, and the old
32
* function name now represents a stub function which calls the
33
* new with the appropriate parameters.
34
*
35
* The new function name is the same in each case as the old function
36
* name, with the addition of a new parameter, cmp_func, which is
37
* used to perform comparisons.
38
*
39
*/
40
41
/*
42
static int add_list_strcmp(List *item1, List *item2)
43
{
44
return strcmp(item1->name, item2->name);
45
}
46
*/
47
48
static int add_list_stricmp(List *item1, List *item2)
49
{
50
return my_stricmp(item1->name, item2->name);
51
}
52
53
/*
54
static int list_strcmp(List *item1, char *str)
55
{
56
return strcmp(item1->name, str);
57
}
58
*/
59
60
static int list_stricmp(List *item1, char *str)
61
{
62
return my_stricmp(item1->name, str);
63
}
64
65
int list_strnicmp(List *item1, char *str)
66
{
67
return my_strnicmp(item1->name, str, strlen(str));
68
}
69
70
static int list_wildstrcmp(List *item1, char *str)
71
{
72
if (wild_match(item1->name, str) || wild_match(str, item1->name))
73
return 0;
74
else
75
return 1;
76
}
77
78
static int list_match(List *item1, char *str)
79
{
80
return wild_match(item1->name, str);
81
}
82
83
/*
84
* add_to_list: This will add an element to a list. The requirements for the
85
* list are that the first element in each list structure be a pointer to the
86
* next element in the list, and the second element in the list structure be
87
* a pointer to a character (char *) which represents the sort key. For
88
* example
89
*
90
* struct my_list{ struct my_list *next; char *name; <whatever else you want>};
91
*
92
* The parameters are: "list" which is a pointer to the head of the list. "add"
93
* which is a pre-allocated element to be added to the list.
94
*/
95
void BX_add_to_list_ext(List **list, List *add, int (*cmp_func)(List *, List *))
96
{
97
register List *tmp;
98
List *last;
99
100
if (!cmp_func)
101
cmp_func = add_list_stricmp;
102
last = NULL;
103
for (tmp = *list; tmp; tmp = tmp->next)
104
{
105
if (cmp_func(tmp, add) > 0)
106
break;
107
last = tmp;
108
}
109
if (last)
110
last->next = add;
111
else
112
*list = add;
113
add->next = tmp;
114
}
115
116
void BX_add_to_list(List **list, List *add)
117
{
118
add_to_list_ext(list, add, NULL);
119
}
120
121
122
/*
123
* find_in_list: This looks up the given name in the given list. List and
124
* name are as described above. If wild is true, each name in the list is
125
* used as a wild card expression to match name... otherwise, normal matching
126
* is done
127
*/
128
List * BX_find_in_list_ext(register List **list, char *name, int wild, int (*cmp_func)(List *, char *))
129
{
130
register List *tmp;
131
int best_match,
132
current_match;
133
134
if (!cmp_func)
135
cmp_func = wild ? list_match : list_stricmp;
136
best_match = 0;
137
138
if (wild)
139
{
140
register List *match = NULL;
141
142
for (tmp = *list; tmp; tmp = tmp->next)
143
{
144
if ((current_match = cmp_func(tmp, name)) > best_match)
145
{
146
match = tmp;
147
best_match = current_match;
148
}
149
}
150
return (match);
151
}
152
else
153
{
154
for (tmp = *list; tmp; tmp = tmp->next)
155
if (cmp_func(tmp, name) == 0)
156
return (tmp);
157
}
158
return NULL;
159
}
160
161
List * BX_find_in_list(List **list, char *name, int wild)
162
{
163
return find_in_list_ext(list, name, wild, NULL);
164
}
165
166
/*
167
* remove_from_list: this remove the given name from the given list (again as
168
* described above). If found, it is removed from the list and returned
169
* (memory is not deallocated). If not found, null is returned.
170
*/
171
List *BX_remove_from_list_ext(List **list, char *name, int (*cmp_func)(List *, char *))
172
{
173
register List *tmp;
174
List *last;
175
176
if (!cmp_func)
177
cmp_func = list_stricmp;
178
last = NULL;
179
for (tmp = *list; tmp; tmp = tmp->next)
180
{
181
if (!cmp_func(tmp, name))
182
{
183
if (last)
184
last->next = tmp->next;
185
else
186
*list = tmp->next;
187
return (tmp);
188
}
189
last = tmp;
190
}
191
return NULL;
192
}
193
194
List *BX_remove_from_list(List **list, char *name)
195
{
196
return remove_from_list_ext(list, name, NULL);
197
}
198
199
List *BX_removewild_from_list(List **list, char *name)
200
{
201
return remove_from_list_ext(list, name, list_wildstrcmp);
202
}
203
204
205
/*
206
* list_lookup: this routine just consolidates remove_from_list and
207
* find_in_list. I did this cause it fit better with some already existing
208
* code
209
*/
210
List *BX_list_lookup_ext(register List **list, char *name, int wild, int delete, int (*cmp_func)(List *, char *))
211
{
212
register List *tmp;
213
214
if (delete)
215
tmp = remove_from_list_ext(list, name, cmp_func);
216
else
217
tmp = find_in_list_ext(list, name, wild, cmp_func);
218
return (tmp);
219
}
220
221
List *BX_list_lookup(List **list, char *name, int wild, int delete)
222
{
223
return list_lookup_ext(list, name, wild, delete, NULL);
224
}
225
226