]> jfr.im git - irc/rqf/shadowircd.git/blob - libratbox/include/rb_tools.h
Remove all the DEFINE's and the random places they were used for the .conf-based...
[irc/rqf/shadowircd.git] / libratbox / include / rb_tools.h
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * tools.h: Header for the various tool functions.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 *
24 */
25
26 #ifndef RB_LIB_H
27 # error "Do not use tools.h directly"
28 #endif
29
30 #ifndef __TOOLS_H__
31 #define __TOOLS_H__
32
33 size_t rb_strlcpy(char *dst, const char *src, size_t siz);
34 size_t rb_strlcat(char *dst, const char *src, size_t siz);
35 size_t rb_strnlen(const char *s, size_t count);
36 char *rb_basename(const char *);
37 char *rb_dirname(const char *);
38
39 int rb_string_to_array(char *string, char **parv, int maxpara);
40
41 /*
42 * double-linked-list stuff
43 */
44 typedef struct _rb_dlink_node rb_dlink_node;
45 typedef struct _rb_dlink_list rb_dlink_list;
46
47 struct _rb_dlink_node
48 {
49 void *data;
50 rb_dlink_node *prev;
51 rb_dlink_node *next;
52
53 };
54
55 struct _rb_dlink_list
56 {
57 rb_dlink_node *head;
58 rb_dlink_node *tail;
59 unsigned long length;
60 };
61
62 rb_dlink_node *rb_make_rb_dlink_node(void);
63 void rb_free_rb_dlink_node(rb_dlink_node *lp);
64 void rb_init_rb_dlink_nodes(size_t dh_size);
65
66 /* This macros are basically swiped from the linux kernel
67 * they are simple yet effective
68 */
69
70 /*
71 * Walks forward of a list.
72 * pos is your node
73 * head is your list head
74 */
75 #define RB_DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
76
77 /*
78 * Walks forward of a list safely while removing nodes
79 * pos is your node
80 * n is another list head for temporary storage
81 * head is your list head
82 */
83 #define RB_DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL)
84
85 #define RB_DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
86
87
88 /* Returns the list length */
89 #define rb_dlink_list_length(list) (list)->length
90
91 #define rb_dlinkAddAlloc(data, list) rb_dlinkAdd(data, rb_make_rb_dlink_node(), list)
92 #define rb_dlinkAddTailAlloc(data, list) rb_dlinkAddTail(data, rb_make_rb_dlink_node(), list)
93 #define rb_dlinkDestroy(node, list) do { rb_dlinkDelete(node, list); rb_free_rb_dlink_node(node); } while(0)
94
95
96 /*
97 * dlink_ routines are stolen from squid, except for rb_dlinkAddBefore,
98 * which is mine.
99 * -- adrian
100 */
101
102 static inline void
103 rb_dlinkMoveNode(rb_dlink_node *m, rb_dlink_list *oldlist, rb_dlink_list *newlist)
104 {
105 /* Assumption: If m->next == NULL, then list->tail == m
106 * and: If m->prev == NULL, then list->head == m
107 */
108 assert(m != NULL);
109 assert(oldlist != NULL);
110 assert(newlist != NULL);
111
112 if(m->next)
113 m->next->prev = m->prev;
114 else
115 oldlist->tail = m->prev;
116
117 if(m->prev)
118 m->prev->next = m->next;
119 else
120 oldlist->head = m->next;
121
122 m->prev = NULL;
123 m->next = newlist->head;
124 if(newlist->head != NULL)
125 newlist->head->prev = m;
126 else if(newlist->tail == NULL)
127 newlist->tail = m;
128 newlist->head = m;
129
130 oldlist->length--;
131 newlist->length++;
132 }
133
134 static inline void
135 rb_dlinkAdd(void *data, rb_dlink_node *m, rb_dlink_list *list)
136 {
137 assert(data != NULL);
138 assert(m != NULL);
139 assert(list != NULL);
140
141 m->data = data;
142 m->prev = NULL;
143 m->next = list->head;
144
145 /* Assumption: If list->tail != NULL, list->head != NULL */
146 if(list->head != NULL)
147 list->head->prev = m;
148 else if(list->tail == NULL)
149 list->tail = m;
150
151 list->head = m;
152 list->length++;
153 }
154
155 static inline void
156 rb_dlinkAddBefore(rb_dlink_node *b, void *data, rb_dlink_node *m, rb_dlink_list *list)
157 {
158 assert(b != NULL);
159 assert(data != NULL);
160 assert(m != NULL);
161 assert(list != NULL);
162
163 /* Shortcut - if its the first one, call rb_dlinkAdd only */
164 if(b == list->head)
165 {
166 rb_dlinkAdd(data, m, list);
167 }
168 else
169 {
170 m->data = data;
171 b->prev->next = m;
172 m->prev = b->prev;
173 b->prev = m;
174 m->next = b;
175 list->length++;
176 }
177 }
178
179 static inline void
180 rb_dlinkMoveTail(rb_dlink_node *m, rb_dlink_list *list)
181 {
182 if(list->tail == m)
183 return;
184
185 /* From here assume that m->next != NULL as that can only
186 * be at the tail and assume that the node is on the list
187 */
188
189 m->next->prev = m->prev;
190
191 if(m->prev != NULL)
192 m->prev->next = m->next;
193 else
194 list->head = m->next;
195
196 list->tail->next = m;
197 m->prev = list->tail;
198 m->next = NULL;
199 list->tail = m;
200 }
201
202 static inline void
203 rb_dlinkAddTail(void *data, rb_dlink_node *m, rb_dlink_list *list)
204 {
205 assert(m != NULL);
206 assert(list != NULL);
207 assert(data != NULL);
208
209 m->data = data;
210 m->next = NULL;
211 m->prev = list->tail;
212
213 /* Assumption: If list->tail != NULL, list->head != NULL */
214 if(list->tail != NULL)
215 list->tail->next = m;
216 else if(list->head == NULL)
217 list->head = m;
218
219 list->tail = m;
220 list->length++;
221 }
222
223 /* Execution profiles show that this function is called the most
224 * often of all non-spontaneous functions. So it had better be
225 * efficient. */
226 static inline void
227 rb_dlinkDelete(rb_dlink_node *m, rb_dlink_list *list)
228 {
229 assert(m != NULL);
230 assert(list != NULL);
231 /* Assumption: If m->next == NULL, then list->tail == m
232 * and: If m->prev == NULL, then list->head == m
233 */
234 if(m->next)
235 m->next->prev = m->prev;
236 else
237 list->tail = m->prev;
238
239 if(m->prev)
240 m->prev->next = m->next;
241 else
242 list->head = m->next;
243
244 m->next = m->prev = NULL;
245 list->length--;
246 }
247
248 static inline rb_dlink_node *
249 rb_dlinkFindDelete(void *data, rb_dlink_list *list)
250 {
251 rb_dlink_node *m;
252 assert(list != NULL);
253 assert(data != NULL);
254 RB_DLINK_FOREACH(m, list->head)
255 {
256 if(m->data != data)
257 continue;
258
259 if(m->next)
260 m->next->prev = m->prev;
261 else
262 list->tail = m->prev;
263
264 if(m->prev)
265 m->prev->next = m->next;
266 else
267 list->head = m->next;
268
269 m->next = m->prev = NULL;
270 list->length--;
271 return m;
272 }
273 return NULL;
274 }
275
276 static inline int
277 rb_dlinkFindDestroy(void *data, rb_dlink_list *list)
278 {
279 void *ptr;
280
281 assert(list != NULL);
282 assert(data != NULL);
283 ptr = rb_dlinkFindDelete(data, list);
284
285 if(ptr != NULL)
286 {
287 rb_free_rb_dlink_node(ptr);
288 return 1;
289 }
290 return 0;
291 }
292
293 /*
294 * rb_dlinkFind
295 * inputs - list to search
296 * - data
297 * output - pointer to link or NULL if not found
298 * side effects - Look for ptr in the linked listed pointed to by link.
299 */
300 static inline rb_dlink_node *
301 rb_dlinkFind(void *data, rb_dlink_list *list)
302 {
303 rb_dlink_node *ptr;
304 assert(list != NULL);
305 assert(data != NULL);
306
307 RB_DLINK_FOREACH(ptr, list->head)
308 {
309 if(ptr->data == data)
310 return (ptr);
311 }
312 return (NULL);
313 }
314
315 static inline void
316 rb_dlinkMoveList(rb_dlink_list *from, rb_dlink_list *to)
317 {
318 assert(from != NULL);
319 assert(to != NULL);
320
321 /* There are three cases */
322 /* case one, nothing in from list */
323 if(from->head == NULL)
324 return;
325
326 /* case two, nothing in to list */
327 if(to->head == NULL)
328 {
329 to->head = from->head;
330 to->tail = from->tail;
331 from->head = from->tail = NULL;
332 to->length = from->length;
333 from->length = 0;
334 return;
335 }
336
337 /* third case play with the links */
338 from->tail->next = to->head;
339 to->head->prev = from->tail;
340 to->head = from->head;
341 from->head = from->tail = NULL;
342 to->length += from->length;
343 from->length = 0;
344 }
345
346 #endif /* __TOOLS_H__ */