1 /*
2 * list.c: some generic linked list managing stuff
3 *
4 * Copyright (c) 1990 Michael Sandroff.
5 * Copyright (c) 1991, 1992 Troy Rollo.
6 * Copyright (c) 1992-1996 Matthew Green.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notices, the above paragraph (the one permitting redistribution),
16 * this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The names of the author(s) may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include "irc.h"
36 #include "list.h"
37 #include "ircaux.h"
38 #include "reg.h"
39
add_list_strcmp(List * item1,List * item2)40 static __inline__ int add_list_strcmp (List *item1, List *item2)
41 {
42 return my_stricmp(item1->name, item2->name);
43 }
44
list_strcmp(List * item1,const char * str)45 static __inline__ int list_strcmp (List *item1, const char *str)
46 {
47 return my_stricmp(item1->name, str);
48 }
49
list_match(List * item1,const char * str)50 static __inline__ int list_match (List *item1, const char *str)
51 {
52 return wild_match(item1->name, str);
53 }
54
55 /*
56 * add_to_list: This will add an element to a list. The requirements for the
57 * list are that the first element in each list structure be a pointer to the
58 * next element in the list, and the second element in the list structure be
59 * a pointer to a character (char *) which represents the sort key. For
60 * example
61 *
62 * struct my_list{ struct my_list *next; char *name; <whatever else you want>};
63 *
64 * The parameters are: "list" which is a pointer to the head of the list. "add"
65 * which is a pre-allocated element to be added to the list.
66 */
add_to_list(List ** list,List * add)67 void add_to_list (List **list, List *add)
68 {
69 List *tmp,
70 *last = NULL;
71
72 for (tmp = *list; tmp; tmp = tmp->next)
73 {
74 if (add_list_strcmp(tmp, add) > 0)
75 break;
76 last = tmp;
77 }
78
79 if (last)
80 last->next = add;
81 else
82 *list = add;
83
84 add->next = tmp;
85 return;
86 }
87
88 /*
89 * find_in_list: This looks up the given name in the given list. List and
90 * name are as described above. If wild is true, each name in the list is
91 * used as a wild card expression to match name... otherwise, normal matching
92 * is done
93 */
find_in_list(List ** list,const char * name,int wild)94 List *find_in_list (List **list, const char *name, int wild)
95 {
96 List *tmp;
97 int best_match = 0,
98 current_match;
99 int (*cmp_func) (List *, const char *);
100
101 cmp_func = wild ? list_match : list_strcmp;
102
103 if (wild)
104 {
105 List *match = (List *) 0;
106
107 for (tmp = *list; tmp; tmp = tmp->next)
108 if ((current_match = cmp_func(tmp, name)) > best_match)
109 match = tmp, best_match = current_match;
110
111 return (match);
112 }
113 else
114 {
115 for (tmp = *list; tmp; tmp = tmp->next)
116 if (cmp_func(tmp, name) == 0)
117 return (tmp);
118 }
119
120 return ((List *) 0);
121 }
122
123 /*
124 * remove_from_list: this remove the given name from the given list (again as
125 * described above). If found, it is removed from the list and returned
126 * (memory is not deallocated). If not found, null is returned.
127 */
remove_from_list(List ** list,const char * name)128 List *remove_from_list (List **list, const char *name)
129 {
130 List *tmp,
131 *last = NULL;
132
133 for (tmp = *list; tmp; tmp = tmp->next)
134 {
135 if (list_strcmp(tmp, name) == 0)
136 {
137 if (last)
138 last->next = tmp->next;
139 else
140 *list = tmp->next;
141 return (tmp);
142 }
143 last = tmp;
144 }
145
146 return ((List *) 0);
147 }
148
149 /*
150 * remove_item_from_list: this remove the given item from the given list
151 * (again as described above). If found, it is removed from the list and
152 * returned (memory is not deallocated). If not found, null is returned.
153 */
remove_item_from_list(List ** list,List * item)154 List * remove_item_from_list (List **list, List *item)
155 {
156 List *tmp,
157 *last = NULL;
158
159 for (tmp = *list; tmp; tmp = tmp->next)
160 {
161 if (tmp == item)
162 {
163 if (last)
164 last->next = tmp->next;
165 else
166 *list = tmp->next;
167 return (tmp);
168 }
169 last = tmp;
170 }
171
172 return NULL;
173 }
174 /*
175 * list_lookup: this routine just consolidates remove_from_list and
176 * find_in_list. I did this cause it fit better with some alread existing
177 * code
178 */
list_lookup(List ** list,const char * name,int wild,int rem)179 List *list_lookup (List **list, const char *name, int wild, int rem)
180 {
181 List *tmp;
182
183 if (rem)
184 tmp = remove_from_list(list, name);
185 else
186 tmp = find_in_list(list, name, wild);
187
188 return (tmp);
189 }
190
191