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