2 * ircd-ratbox: A slightly useful ircd.
3 * tools.h: Header for the various tool functions.
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
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.
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.
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
24 * $Id: rb_tools.h 25042 2008-01-23 16:14:08Z androsyn $
28 # error "Do not use tools.h directly"
34 size_t rb_strlcpy(char *dst
, const char *src
, size_t siz
);
35 size_t rb_strlcat(char *dst
, const char *src
, size_t siz
);
36 size_t rb_strnlen(const char *s
, size_t count
);
38 int rb_string_to_array(char *string
, char **parv
, int maxpara
);
41 * double-linked-list stuff
43 typedef struct _rb_dlink_node rb_dlink_node
;
44 typedef struct _rb_dlink_list rb_dlink_list
;
61 rb_dlink_node
*rb_make_rb_dlink_node(void);
62 void rb_free_rb_dlink_node(rb_dlink_node
* lp
);
63 void rb_init_rb_dlink_nodes(size_t dh_size
);
65 /* This macros are basically swiped from the linux kernel
66 * they are simple yet effective
70 * Walks forward of a list.
72 * head is your list head
74 #define RB_DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
77 * Walks forward of a list safely while removing nodes
79 * n is another list head for temporary storage
80 * head is your list head
82 #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 #define RB_DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
87 /* Returns the list length */
88 #define rb_dlink_list_length(list) (list)->length
90 #define rb_dlinkAddAlloc(data, list) rb_dlinkAdd(data, rb_make_rb_dlink_node(), list)
91 #define rb_dlinkAddTailAlloc(data, list) rb_dlinkAddTail(data, rb_make_rb_dlink_node(), list)
92 #define rb_dlinkDestroy(node, list) do { rb_dlinkDelete(node, list); rb_free_rb_dlink_node(node); } while(0)
96 * dlink_ routines are stolen from squid, except for rb_dlinkAddBefore,
102 rb_dlinkMoveNode(rb_dlink_node
* m
, rb_dlink_list
* oldlist
, rb_dlink_list
* newlist
)
104 /* Assumption: If m->next == NULL, then list->tail == m
105 * and: If m->prev == NULL, then list->head == m
108 assert(oldlist
!= NULL
);
109 assert(newlist
!= NULL
);
112 m
->next
->prev
= m
->prev
;
114 oldlist
->tail
= m
->prev
;
117 m
->prev
->next
= m
->next
;
119 oldlist
->head
= m
->next
;
122 m
->next
= newlist
->head
;
123 if(newlist
->head
!= NULL
)
124 newlist
->head
->prev
= m
;
125 else if(newlist
->tail
== NULL
)
134 rb_dlinkAdd(void *data
, rb_dlink_node
* m
, rb_dlink_list
* list
)
136 assert(data
!= NULL
);
138 assert(list
!= NULL
);
142 m
->next
= list
->head
;
144 /* Assumption: If list->tail != NULL, list->head != NULL */
145 if(list
->head
!= NULL
)
146 list
->head
->prev
= m
;
147 else if(list
->tail
== NULL
)
155 rb_dlinkAddBefore(rb_dlink_node
* b
, void *data
, rb_dlink_node
* m
, rb_dlink_list
* list
)
158 assert(data
!= NULL
);
160 assert(list
!= NULL
);
162 /* Shortcut - if its the first one, call rb_dlinkAdd only */
165 rb_dlinkAdd(data
, m
, list
);
179 rb_dlinkMoveTail(rb_dlink_node
*m
, rb_dlink_list
*list
)
184 /* From here assume that m->next != NULL as that can only
185 * be at the tail and assume that the node is on the list
188 m
->next
->prev
= m
->prev
;
191 m
->prev
->next
= m
->next
;
193 list
->head
= m
->next
;
195 list
->tail
->next
= m
;
196 m
->prev
= list
->tail
;
202 rb_dlinkAddTail(void *data
, rb_dlink_node
* m
, rb_dlink_list
* list
)
205 assert(list
!= NULL
);
206 assert(data
!= NULL
);
210 m
->prev
= list
->tail
;
212 /* Assumption: If list->tail != NULL, list->head != NULL */
213 if(list
->tail
!= NULL
)
214 list
->tail
->next
= m
;
215 else if(list
->head
== NULL
)
222 /* Execution profiles show that this function is called the most
223 * often of all non-spontaneous functions. So it had better be
226 rb_dlinkDelete(rb_dlink_node
* m
, rb_dlink_list
* list
)
229 assert(list
!= NULL
);
230 /* Assumption: If m->next == NULL, then list->tail == m
231 * and: If m->prev == NULL, then list->head == m
234 m
->next
->prev
= m
->prev
;
236 list
->tail
= m
->prev
;
239 m
->prev
->next
= m
->next
;
241 list
->head
= m
->next
;
243 m
->next
= m
->prev
= NULL
;
247 static inline rb_dlink_node
*
248 rb_dlinkFindDelete(void *data
, rb_dlink_list
*list
)
251 assert(list
!= NULL
);
252 assert(data
!= NULL
);
253 RB_DLINK_FOREACH(m
, list
->head
)
259 m
->next
->prev
= m
->prev
;
261 list
->tail
= m
->prev
;
264 m
->prev
->next
= m
->next
;
266 list
->head
= m
->next
;
268 m
->next
= m
->prev
= NULL
;
276 rb_dlinkFindDestroy(void *data
, rb_dlink_list
*list
)
280 assert(list
!= NULL
);
281 assert(data
!= NULL
);
282 ptr
= rb_dlinkFindDelete(data
, list
);
286 rb_free_rb_dlink_node(ptr
);
294 * inputs - list to search
296 * output - pointer to link or NULL if not found
297 * side effects - Look for ptr in the linked listed pointed to by link.
299 static inline rb_dlink_node
*
300 rb_dlinkFind(void *data
, rb_dlink_list
*list
)
303 assert(list
!= NULL
);
304 assert(data
!= NULL
);
306 RB_DLINK_FOREACH(ptr
, list
->head
)
308 if(ptr
->data
== data
)
315 rb_dlinkMoveList(rb_dlink_list
* from
, rb_dlink_list
* to
)
317 assert(from
!= NULL
);
320 /* There are three cases */
321 /* case one, nothing in from list */
322 if(from
->head
== NULL
)
325 /* case two, nothing in to list */
328 to
->head
= from
->head
;
329 to
->tail
= from
->tail
;
330 from
->head
= from
->tail
= NULL
;
331 to
->length
= from
->length
;
336 /* third case play with the links */
337 from
->tail
->next
= to
->head
;
338 to
->head
->prev
= from
->tail
;
339 to
->head
= from
->head
;
340 from
->head
= from
->tail
= NULL
;
341 to
->length
+= from
->length
;
345 #endif /* __TOOLS_H__ */