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
27 # error "Do not use tools.h directly"
33 int rb_strcasecmp(const char *s1
, const char *s2
);
34 int rb_strncasecmp(const char *s1
, const char *s2
, size_t n
);
35 char *rb_strcasestr(const char *s
, const char *find
);
36 size_t rb_strlcpy(char *dst
, const char *src
, size_t siz
);
37 size_t rb_strlcat(char *dst
, const char *src
, size_t siz
);
38 size_t rb_strnlen(const char *s
, size_t count
);
39 int rb_snprintf_append(char *str
, size_t len
, const char *format
, ...) AFP(3,4);
40 int rb_snprintf_try_append(char *str
, size_t len
, const char *format
, ...) AFP(3,4);
42 char *rb_basename(const char *);
43 char *rb_dirname(const char *);
45 int rb_string_to_array(char *string
, char **parv
, int maxpara
);
48 * double-linked-list stuff
50 typedef struct _rb_dlink_node rb_dlink_node
;
51 typedef struct _rb_dlink_list rb_dlink_list
;
68 rb_dlink_node
*rb_make_rb_dlink_node(void);
69 void rb_free_rb_dlink_node(rb_dlink_node
*lp
);
70 void rb_init_rb_dlink_nodes(size_t dh_size
);
72 /* This macros are basically swiped from the linux kernel
73 * they are simple yet effective
77 * Walks forward of a list.
79 * head is your list head
81 #define RB_DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
84 * Walks forward of a list safely while removing nodes
86 * n is another list head for temporary storage
87 * head is your list head
89 #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)
91 #define RB_DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
94 /* Returns the list length */
95 #define rb_dlink_list_length(list) (list)->length
97 #define rb_dlinkAddAlloc(data, list) rb_dlinkAdd(data, rb_make_rb_dlink_node(), list)
98 #define rb_dlinkAddTailAlloc(data, list) rb_dlinkAddTail(data, rb_make_rb_dlink_node(), list)
99 #define rb_dlinkDestroy(node, list) do { rb_dlinkDelete(node, list); rb_free_rb_dlink_node(node); } while(0)
103 * dlink_ routines are stolen from squid, except for rb_dlinkAddBefore,
109 rb_dlinkMoveNode(rb_dlink_node
*m
, rb_dlink_list
*oldlist
, rb_dlink_list
*newlist
)
111 /* Assumption: If m->next == NULL, then list->tail == m
112 * and: If m->prev == NULL, then list->head == m
115 assert(oldlist
!= NULL
);
116 assert(newlist
!= NULL
);
119 m
->next
->prev
= m
->prev
;
121 oldlist
->tail
= m
->prev
;
124 m
->prev
->next
= m
->next
;
126 oldlist
->head
= m
->next
;
129 m
->next
= newlist
->head
;
130 if(newlist
->head
!= NULL
)
131 newlist
->head
->prev
= m
;
132 else if(newlist
->tail
== NULL
)
141 rb_dlinkAdd(void *data
, rb_dlink_node
*m
, rb_dlink_list
*list
)
143 assert(data
!= NULL
);
145 assert(list
!= NULL
);
149 m
->next
= list
->head
;
151 /* Assumption: If list->tail != NULL, list->head != NULL */
152 if(list
->head
!= NULL
)
153 list
->head
->prev
= m
;
154 else if(list
->tail
== NULL
)
162 rb_dlinkAddBefore(rb_dlink_node
*b
, void *data
, rb_dlink_node
*m
, rb_dlink_list
*list
)
165 assert(data
!= NULL
);
167 assert(list
!= NULL
);
169 /* Shortcut - if its the first one, call rb_dlinkAdd only */
172 rb_dlinkAdd(data
, m
, list
);
186 rb_dlinkMoveTail(rb_dlink_node
*m
, rb_dlink_list
*list
)
191 /* From here assume that m->next != NULL as that can only
192 * be at the tail and assume that the node is on the list
195 m
->next
->prev
= m
->prev
;
198 m
->prev
->next
= m
->next
;
200 list
->head
= m
->next
;
202 list
->tail
->next
= m
;
203 m
->prev
= list
->tail
;
209 rb_dlinkAddTail(void *data
, rb_dlink_node
*m
, rb_dlink_list
*list
)
212 assert(list
!= NULL
);
213 assert(data
!= NULL
);
217 m
->prev
= list
->tail
;
219 /* Assumption: If list->tail != NULL, list->head != NULL */
220 if(list
->tail
!= NULL
)
221 list
->tail
->next
= m
;
222 else if(list
->head
== NULL
)
229 /* Execution profiles show that this function is called the most
230 * often of all non-spontaneous functions. So it had better be
233 rb_dlinkDelete(rb_dlink_node
*m
, rb_dlink_list
*list
)
236 assert(list
!= NULL
);
237 /* Assumption: If m->next == NULL, then list->tail == m
238 * and: If m->prev == NULL, then list->head == m
241 m
->next
->prev
= m
->prev
;
243 list
->tail
= m
->prev
;
246 m
->prev
->next
= m
->next
;
248 list
->head
= m
->next
;
250 m
->next
= m
->prev
= NULL
;
254 static inline rb_dlink_node
*
255 rb_dlinkFindDelete(void *data
, rb_dlink_list
*list
)
258 assert(list
!= NULL
);
259 assert(data
!= NULL
);
260 RB_DLINK_FOREACH(m
, list
->head
)
266 m
->next
->prev
= m
->prev
;
268 list
->tail
= m
->prev
;
271 m
->prev
->next
= m
->next
;
273 list
->head
= m
->next
;
275 m
->next
= m
->prev
= NULL
;
283 rb_dlinkFindDestroy(void *data
, rb_dlink_list
*list
)
287 assert(list
!= NULL
);
288 assert(data
!= NULL
);
289 ptr
= rb_dlinkFindDelete(data
, list
);
293 rb_free_rb_dlink_node(ptr
);
301 * inputs - list to search
303 * output - pointer to link or NULL if not found
304 * side effects - Look for ptr in the linked listed pointed to by link.
306 static inline rb_dlink_node
*
307 rb_dlinkFind(void *data
, rb_dlink_list
*list
)
310 assert(list
!= NULL
);
311 assert(data
!= NULL
);
313 RB_DLINK_FOREACH(ptr
, list
->head
)
315 if(ptr
->data
== data
)
322 rb_dlinkMoveList(rb_dlink_list
*from
, rb_dlink_list
*to
)
324 assert(from
!= NULL
);
327 /* There are three cases */
328 /* case one, nothing in from list */
329 if(from
->head
== NULL
)
332 /* case two, nothing in to list */
335 to
->head
= from
->head
;
336 to
->tail
= from
->tail
;
337 from
->head
= from
->tail
= NULL
;
338 to
->length
= from
->length
;
343 /* third case play with the links */
344 from
->tail
->next
= to
->head
;
345 to
->head
->prev
= from
->tail
;
346 to
->head
= from
->head
;
347 from
->head
= from
->tail
= NULL
;
348 to
->length
+= from
->length
;
353 typedef int (*rb_strf_func_t
)(char *buf
, size_t len
, void *args
);
355 typedef struct _rb_strf
{
356 size_t length
; /* length limit to apply to this string (and following strings if their length is 0) */
357 const char *format
; /* string or format string */
358 rb_strf_func_t func
; /* function to print to string */
360 va_list *format_args
; /* non-NULL if this is a format string */
361 void *func_args
; /* args for a function */
363 const struct _rb_strf
*next
; /* next string to append */
366 int rb_fsnprint(char *buf
, size_t len
, const rb_strf_t
*strings
);
367 int rb_fsnprintf(char *buf
, size_t len
, const rb_strf_t
*strings
, const char *format
, ...) AFP(4, 5);
370 const char *rb_path_to_self(void);
372 #endif /* __TOOLS_H__ */