]>
jfr.im git - solanum.git/blob - libcharybdis/tools.h
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-2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 * $Id: tools.h 3201 2007-02-04 01:59:38Z jilles $
32 * double-linked-list stuff
34 typedef struct _dlink_node dlink_node
;
35 typedef struct _dlink_list dlink_list
;
52 dlink_node
*make_dlink_node(void);
53 void free_dlink_node(dlink_node
* lp
);
54 void init_dlink_nodes(void);
57 void mem_frob(void *data
, int len
);
59 #define mem_frob(x, y)
62 /* This macros are basically swiped from the linux kernel
63 * they are simple yet effective
67 * Walks forward of a list.
69 * head is your list head
71 #define DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
74 * Walks forward of a list safely while removing nodes
76 * n is another list head for temporary storage
77 * head is your list head
79 #define DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL)
81 #define DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
84 /* Returns the list length */
85 #define dlink_list_length(list) (list)->length
86 #define dlink_move_list(oldlist, newlist, node)
88 #define dlinkAddAlloc(data, list) dlinkAdd(data, make_dlink_node(), list)
89 #define dlinkAddTailAlloc(data, list) dlinkAddTail(data, make_dlink_node(), list)
90 #define dlinkDestroy(node, list) do { dlinkDelete(node, list); free_dlink_node(node); } while(0)
94 * The functions below are included for the sake of inlining
95 * hopefully this will speed up things just a bit
100 * dlink_ routines are stolen from squid, except for dlinkAddBefore,
105 /* I hate C sometimes */
106 #if defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__
107 #define INLINE_FUNC extern inline
119 void dlinkMoveNode(dlink_node
* m
, dlink_list
* oldlist
, dlink_list
* newlist
);
120 void dlinkAdd(void *data
, dlink_node
* m
, dlink_list
* list
);
121 void dlinkAddBefore(dlink_node
* b
, void *data
, dlink_node
* m
, dlink_list
* list
);
122 void dlinkMoveTail(dlink_node
*m
, dlink_list
*list
);
123 void dlinkAddTail(void *data
, dlink_node
* m
, dlink_list
* list
);
124 void dlinkDelete(dlink_node
* m
, dlink_list
* list
);
125 dlink_node
*dlinkFindDelete(void *data
, dlink_list
*list
);
126 int dlinkFindDestroy(void *data
, dlink_list
*list
);
127 dlink_node
*dlinkFind(void *data
, dlink_list
*list
);
128 void dlinkMoveList(dlink_list
* from
, dlink_list
* to
);
130 #if defined(NEED_INLINES) || defined(TOOLS_C)
132 dlinkMoveNode(dlink_node
* m
, dlink_list
* oldlist
, dlink_list
* newlist
)
134 /* Assumption: If m->next == NULL, then list->tail == m
135 * and: If m->prev == NULL, then list->head == m
138 assert(oldlist
!= NULL
);
139 assert(newlist
!= NULL
);
142 m
->next
->prev
= m
->prev
;
144 oldlist
->tail
= m
->prev
;
147 m
->prev
->next
= m
->next
;
149 oldlist
->head
= m
->next
;
152 m
->next
= newlist
->head
;
153 if(newlist
->head
!= NULL
)
154 newlist
->head
->prev
= m
;
155 else if(newlist
->tail
== NULL
)
164 dlinkAdd(void *data
, dlink_node
* m
, dlink_list
* list
)
166 assert(data
!= NULL
);
168 assert(list
!= NULL
);
171 m
->next
= list
->head
;
173 /* Assumption: If list->tail != NULL, list->head != NULL */
174 if(list
->head
!= NULL
)
175 list
->head
->prev
= m
;
176 else if(list
->tail
== NULL
)
184 dlinkAddBefore(dlink_node
* b
, void *data
, dlink_node
* m
, dlink_list
* list
)
187 assert(data
!= NULL
);
189 assert(list
!= NULL
);
191 /* Shortcut - if its the first one, call dlinkAdd only */
194 dlinkAdd(data
, m
, list
);
208 dlinkMoveTail(dlink_node
*m
, dlink_list
*list
)
213 /* From here assume that m->next != NULL as that can only
214 * be at the tail and assume that the node is on the list
217 m
->next
->prev
= m
->prev
;
220 m
->prev
->next
= m
->next
;
222 list
->head
= m
->next
;
224 list
->tail
->next
= m
;
225 m
->prev
= list
->tail
;
231 dlinkAddTail(void *data
, dlink_node
* m
, dlink_list
* list
)
234 assert(list
!= NULL
);
235 assert(data
!= NULL
);
238 m
->prev
= list
->tail
;
240 /* Assumption: If list->tail != NULL, list->head != NULL */
241 if(list
->tail
!= NULL
)
242 list
->tail
->next
= m
;
243 else if(list
->head
== NULL
)
250 /* Execution profiles show that this function is called the most
251 * often of all non-spontaneous functions. So it had better be
254 dlinkDelete(dlink_node
* m
, dlink_list
* list
)
257 assert(list
!= NULL
);
259 /* Assumption: If m->next == NULL, then list->tail == m
260 * and: If m->prev == NULL, then list->head == m
263 m
->next
->prev
= m
->prev
;
265 list
->tail
= m
->prev
;
268 m
->prev
->next
= m
->next
;
270 list
->head
= m
->next
;
272 m
->next
= m
->prev
= NULL
;
276 INLINE_FUNC dlink_node
*
277 dlinkFindDelete(void *data
, dlink_list
*list
)
280 assert(list
!= NULL
);
281 assert(data
!= NULL
);
283 DLINK_FOREACH(m
, list
->head
)
289 m
->next
->prev
= m
->prev
;
291 list
->tail
= m
->prev
;
294 m
->prev
->next
= m
->next
;
296 list
->head
= m
->next
;
298 m
->next
= m
->prev
= NULL
;
307 dlinkFindDestroy(void *data
, dlink_list
*list
)
311 assert(list
!= NULL
);
312 assert(data
!= NULL
);
314 ptr
= dlinkFindDelete(data
, list
);
318 free_dlink_node(ptr
);
326 * inputs - list to search
328 * output - pointer to link or NULL if not found
329 * side effects - Look for ptr in the linked listed pointed to by link.
331 INLINE_FUNC dlink_node
*
332 dlinkFind(void *data
, dlink_list
*list
)
335 assert(list
!= NULL
);
336 assert(data
!= NULL
);
338 DLINK_FOREACH(ptr
, list
->head
)
340 if(ptr
->data
== data
)
347 dlinkMoveList(dlink_list
* from
, dlink_list
* to
)
349 assert(from
!= NULL
);
352 /* There are three cases */
353 /* case one, nothing in from list */
354 if(from
->head
== NULL
)
357 /* case two, nothing in to list */
360 to
->head
= from
->head
;
361 to
->tail
= from
->tail
;
362 from
->head
= from
->tail
= NULL
;
363 to
->length
= from
->length
;
368 /* third case play with the links */
369 from
->tail
->next
= to
->head
;
370 to
->head
->prev
= from
->tail
;
371 to
->head
= from
->head
;
372 from
->head
= from
->tail
= NULL
;
373 to
->length
+= from
->length
;
378 #endif /* __TOOLS_H__ */