]> jfr.im git - solanum.git/blame - librb/include/rb_tools.h
rename libratbox to librb, since its pretty modified anyway
[solanum.git] / librb / include / rb_tools.h
CommitLineData
db137867
AC
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 *
3202e249 24 * $Id: rb_tools.h 26170 2008-10-26 20:59:07Z androsyn $
db137867
AC
25 */
26
27#ifndef RB_LIB_H
3202e249 28# error "Do not use tools.h directly"
db137867
AC
29#endif
30
31#ifndef __TOOLS_H__
32#define __TOOLS_H__
33
34size_t rb_strlcpy(char *dst, const char *src, size_t siz);
35size_t rb_strlcat(char *dst, const char *src, size_t siz);
36size_t rb_strnlen(const char *s, size_t count);
5203cba5
VI
37
38#ifdef __GNUC__
39int rb_snprintf_append(char *str, size_t len, const char *format, ...)
40 __attribute__ ((format(printf, 3, 4)));
41#else
42int rb_snprintf_append(char *str, const size_t size, const char *, ...);
43#endif
44
3202e249
VY
45char *rb_basename(const char *);
46char *rb_dirname(const char *);
db137867
AC
47
48int rb_string_to_array(char *string, char **parv, int maxpara);
49
50/*
51 * double-linked-list stuff
52 */
53typedef struct _rb_dlink_node rb_dlink_node;
54typedef struct _rb_dlink_list rb_dlink_list;
55
56struct _rb_dlink_node
57{
58 void *data;
59 rb_dlink_node *prev;
60 rb_dlink_node *next;
61
62};
63
64struct _rb_dlink_list
65{
66 rb_dlink_node *head;
67 rb_dlink_node *tail;
68 unsigned long length;
69};
70
71rb_dlink_node *rb_make_rb_dlink_node(void);
3202e249 72void rb_free_rb_dlink_node(rb_dlink_node *lp);
db137867
AC
73void rb_init_rb_dlink_nodes(size_t dh_size);
74
75/* This macros are basically swiped from the linux kernel
76 * they are simple yet effective
77 */
78
79/*
55abcbb2 80 * Walks forward of a list.
db137867
AC
81 * pos is your node
82 * head is your list head
83 */
84#define RB_DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
85
86/*
55abcbb2 87 * Walks forward of a list safely while removing nodes
db137867
AC
88 * pos is your node
89 * n is another list head for temporary storage
90 * head is your list head
91 */
92#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)
93
94#define RB_DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
95
96
97/* Returns the list length */
98#define rb_dlink_list_length(list) (list)->length
99
100#define rb_dlinkAddAlloc(data, list) rb_dlinkAdd(data, rb_make_rb_dlink_node(), list)
101#define rb_dlinkAddTailAlloc(data, list) rb_dlinkAddTail(data, rb_make_rb_dlink_node(), list)
102#define rb_dlinkDestroy(node, list) do { rb_dlinkDelete(node, list); rb_free_rb_dlink_node(node); } while(0)
103
104
55abcbb2 105/*
db137867
AC
106 * dlink_ routines are stolen from squid, except for rb_dlinkAddBefore,
107 * which is mine.
108 * -- adrian
109 */
110
111static inline void
3202e249 112rb_dlinkMoveNode(rb_dlink_node *m, rb_dlink_list *oldlist, rb_dlink_list *newlist)
db137867
AC
113{
114 /* Assumption: If m->next == NULL, then list->tail == m
115 * and: If m->prev == NULL, then list->head == m
116 */
117 assert(m != NULL);
118 assert(oldlist != NULL);
119 assert(newlist != NULL);
120
121 if(m->next)
122 m->next->prev = m->prev;
123 else
124 oldlist->tail = m->prev;
125
126 if(m->prev)
127 m->prev->next = m->next;
128 else
129 oldlist->head = m->next;
130
131 m->prev = NULL;
132 m->next = newlist->head;
133 if(newlist->head != NULL)
134 newlist->head->prev = m;
135 else if(newlist->tail == NULL)
136 newlist->tail = m;
137 newlist->head = m;
138
139 oldlist->length--;
140 newlist->length++;
141}
142
143static inline void
3202e249 144rb_dlinkAdd(void *data, rb_dlink_node *m, rb_dlink_list *list)
db137867
AC
145{
146 assert(data != NULL);
147 assert(m != NULL);
148 assert(list != NULL);
149
150 m->data = data;
151 m->prev = NULL;
152 m->next = list->head;
153
154 /* Assumption: If list->tail != NULL, list->head != NULL */
155 if(list->head != NULL)
156 list->head->prev = m;
157 else if(list->tail == NULL)
158 list->tail = m;
159
160 list->head = m;
161 list->length++;
162}
163
164static inline void
3202e249 165rb_dlinkAddBefore(rb_dlink_node *b, void *data, rb_dlink_node *m, rb_dlink_list *list)
db137867
AC
166{
167 assert(b != NULL);
168 assert(data != NULL);
169 assert(m != NULL);
170 assert(list != NULL);
171
172 /* Shortcut - if its the first one, call rb_dlinkAdd only */
173 if(b == list->head)
174 {
175 rb_dlinkAdd(data, m, list);
176 }
177 else
178 {
179 m->data = data;
180 b->prev->next = m;
181 m->prev = b->prev;
182 b->prev = m;
183 m->next = b;
184 list->length++;
185 }
186}
187
188static inline void
189rb_dlinkMoveTail(rb_dlink_node *m, rb_dlink_list *list)
190{
191 if(list->tail == m)
192 return;
3202e249 193
55abcbb2 194 /* From here assume that m->next != NULL as that can only
db137867
AC
195 * be at the tail and assume that the node is on the list
196 */
3202e249 197
db137867
AC
198 m->next->prev = m->prev;
199
200 if(m->prev != NULL)
201 m->prev->next = m->next;
202 else
203 list->head = m->next;
204
205 list->tail->next = m;
206 m->prev = list->tail;
207 m->next = NULL;
208 list->tail = m;
209}
210
211static inline void
3202e249 212rb_dlinkAddTail(void *data, rb_dlink_node *m, rb_dlink_list *list)
db137867
AC
213{
214 assert(m != NULL);
215 assert(list != NULL);
216 assert(data != NULL);
217
218 m->data = data;
219 m->next = NULL;
220 m->prev = list->tail;
221
222 /* Assumption: If list->tail != NULL, list->head != NULL */
223 if(list->tail != NULL)
224 list->tail->next = m;
225 else if(list->head == NULL)
226 list->head = m;
227
228 list->tail = m;
229 list->length++;
230}
231
232/* Execution profiles show that this function is called the most
233 * often of all non-spontaneous functions. So it had better be
234 * efficient. */
235static inline void
3202e249 236rb_dlinkDelete(rb_dlink_node *m, rb_dlink_list *list)
db137867
AC
237{
238 assert(m != NULL);
239 assert(list != NULL);
240 /* Assumption: If m->next == NULL, then list->tail == m
241 * and: If m->prev == NULL, then list->head == m
242 */
243 if(m->next)
244 m->next->prev = m->prev;
245 else
246 list->tail = m->prev;
247
248 if(m->prev)
249 m->prev->next = m->next;
250 else
251 list->head = m->next;
252
253 m->next = m->prev = NULL;
254 list->length--;
255}
256
257static inline rb_dlink_node *
258rb_dlinkFindDelete(void *data, rb_dlink_list *list)
259{
260 rb_dlink_node *m;
261 assert(list != NULL);
262 assert(data != NULL);
263 RB_DLINK_FOREACH(m, list->head)
264 {
265 if(m->data != data)
266 continue;
267
268 if(m->next)
269 m->next->prev = m->prev;
270 else
271 list->tail = m->prev;
272
273 if(m->prev)
274 m->prev->next = m->next;
275 else
276 list->head = m->next;
277
278 m->next = m->prev = NULL;
279 list->length--;
280 return m;
281 }
282 return NULL;
283}
284
285static inline int
286rb_dlinkFindDestroy(void *data, rb_dlink_list *list)
287{
288 void *ptr;
289
290 assert(list != NULL);
291 assert(data != NULL);
292 ptr = rb_dlinkFindDelete(data, list);
293
294 if(ptr != NULL)
295 {
296 rb_free_rb_dlink_node(ptr);
297 return 1;
298 }
299 return 0;
300}
301
302/*
303 * rb_dlinkFind
55abcbb2 304 * inputs - list to search
db137867
AC
305 * - data
306 * output - pointer to link or NULL if not found
307 * side effects - Look for ptr in the linked listed pointed to by link.
308 */
309static inline rb_dlink_node *
310rb_dlinkFind(void *data, rb_dlink_list *list)
311{
312 rb_dlink_node *ptr;
313 assert(list != NULL);
314 assert(data != NULL);
3202e249 315
db137867
AC
316 RB_DLINK_FOREACH(ptr, list->head)
317 {
318 if(ptr->data == data)
319 return (ptr);
320 }
321 return (NULL);
322}
323
324static inline void
3202e249 325rb_dlinkMoveList(rb_dlink_list *from, rb_dlink_list *to)
db137867
AC
326{
327 assert(from != NULL);
328 assert(to != NULL);
329
330 /* There are three cases */
331 /* case one, nothing in from list */
332 if(from->head == NULL)
333 return;
334
335 /* case two, nothing in to list */
336 if(to->head == NULL)
337 {
338 to->head = from->head;
339 to->tail = from->tail;
340 from->head = from->tail = NULL;
341 to->length = from->length;
342 from->length = 0;
343 return;
344 }
345
346 /* third case play with the links */
347 from->tail->next = to->head;
348 to->head->prev = from->tail;
349 to->head = from->head;
350 from->head = from->tail = NULL;
351 to->length += from->length;
352 from->length = 0;
353}
354
5225f83d
AC
355typedef struct _rb_zstring
356{
357 uint16_t len; /* big enough */
358 uint16_t alloclen;
359 uint8_t *data;
360} rb_zstring_t;
361
362size_t rb_zstring_serialized(rb_zstring_t *zs, void **buf, size_t *buflen);
363size_t rb_zstring_deserialize(rb_zstring_t *zs, void *buf);
364void rb_zstring_free(rb_zstring_t *zs);
365rb_zstring_t *rb_zstring_alloc(void);
366rb_zstring_t *rb_zstring_from_c_len(const char *buf, size_t len);
367rb_zstring_t *rb_zstring_from_c(const char *buf);
368size_t rb_zstring_len(rb_zstring_t *zs);
369void rb_zstring_append_from_zstring(rb_zstring_t *dst_zs, rb_zstring_t *src_zs);
370void rb_zstring_append_from_c(rb_zstring_t *zs, const char *buf, size_t len);
371char *rb_zstring_to_c(rb_zstring_t *zs, char *buf, size_t len);
372char *rb_zstring_to_c_alloc(rb_zstring_t *zs);
373size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr);
374
db137867 375#endif /* __TOOLS_H__ */