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