]>
jfr.im git - solanum.git/blob - librb/src/tools.c
2 * ircd-ratbox: A slightly useful ircd.
3 * tools.c: Various functions needed here and there.
5 * Copyright (C) 1996-2002 Hybrid Development Team
6 * Copyright (C) 2002-2005 ircd-ratbox development team
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
24 * Here is the original header:
26 * Useful stuff, ripped from places ..
27 * adrian chadd <adrian@creative.net.au>
29 * The TOOLS_C define builds versions of the functions in tools.h
30 * so that they end up in the resulting object files. If its not
31 * defined, tools.h will build inlined versions of the functions
32 * on supported compilers
36 #include <librb_config.h>
45 static rb_bh
*dnode_heap
;
47 rb_init_rb_dlink_nodes(size_t dh_size
)
50 dnode_heap
= rb_bh_create(sizeof(rb_dlink_node
), dh_size
, "librb_dnode_heap");
51 if(dnode_heap
== NULL
)
59 * output - pointer to new rb_dlink_node
63 rb_make_rb_dlink_node(void)
65 return (rb_bh_alloc(dnode_heap
));
71 * inputs - pointer to rb_dlink_node
73 * side effects - free given rb_dlink_node
76 rb_free_rb_dlink_node(rb_dlink_node
*ptr
)
79 rb_bh_free(dnode_heap
, ptr
);
82 /* rb_string_to_array()
83 * Changes a given buffer into an array of parameters.
84 * Taken from ircd-ratbox.
86 * inputs - string to parse, array to put in (size >= maxpara)
87 * outputs - number of parameters
90 rb_string_to_array(char *string
, char **parv
, int maxpara
)
92 char *p
, *xbuf
= string
;
95 if(string
== NULL
|| string
[0] == '\0')
98 while(*xbuf
== ' ') /* skip leading spaces */
100 if(*xbuf
== '\0') /* ignore all-space args */
105 if(*xbuf
== ':') /* Last parameter */
114 if((p
= strchr(xbuf
, ' ')) != NULL
)
127 while(x
< maxpara
- 1);
136 #ifndef HAVE_STRCASECMP
138 /* Fallback taken from FreeBSD. --Elizafox */
140 rb_strcasecmp(const char *s1
, const char *s2
)
142 const unsigned char *us1
= (const unsigned char *)s1
;
143 const unsigned char *us2
= (const unsigned char *)s2
;
145 while (tolower(*us1
) == tolower(*us2
++))
151 return (tolower(*us1
) - tolower(*--us2
));
155 rb_strcasecmp(const char *s1
, const char *s2
)
157 return stricmp(s1
, s2
);
160 #else /* HAVE_STRCASECMP */
162 rb_strcasecmp(const char *s1
, const char *s2
)
164 return strcasecmp(s1
, s2
);
168 #ifndef HAVE_STRNCASECMP
170 /* Fallback taken from FreeBSD. --Elizafox */
172 rb_strncasecmp(const char *s1
, const char *s2
, size_t n
)
176 const unsigned char *us1
= (const unsigned char *)s1
;
177 const unsigned char *us2
= (const unsigned char *)s2
;
181 if (tolower(*us1
) != tolower(*us2
++))
182 return (tolower(*us1
) - tolower(*--us2
));
191 rb_strncasecmp(const char *s1
, const char *s2
, size_t n
)
193 return strnicmp(s1
, s2
, n
);
196 #else /* HAVE_STRNCASECMP */
198 rb_strncasecmp(const char *s1
, const char *s2
, size_t n
)
200 return strncasecmp(s1
, s2
, n
);
204 #ifndef HAVE_STRCASESTR
205 /* Fallback taken from FreeBSD. --Elizafox */
207 rb_strcasestr(const char *s
, const char *find
)
212 if ((c
= *find
++) != 0) {
213 c
= tolower((unsigned char)c
);
217 if ((sc
= *s
++) == 0)
219 } while ((char)tolower((unsigned char)sc
) != c
);
220 } while (rb_strncasecmp(s
, find
, len
) != 0);
227 rb_strcasestr(const char *s
, const char *find
)
229 return strcasestr(s
, find
);
235 rb_strlcat(char *dest
, const char *src
, size_t count
)
237 size_t dsize
= strlen(dest
);
238 size_t len
= strlen(src
);
239 size_t res
= dsize
+ len
;
245 memcpy(dest
, src
, len
);
251 rb_strlcat(char *dest
, const char *src
, size_t count
)
253 return strlcat(dest
, src
, count
);
259 rb_strlcpy(char *dest
, const char *src
, size_t size
)
261 size_t ret
= strlen(src
);
265 size_t len
= (ret
>= size
) ? size
- 1 : ret
;
266 memcpy(dest
, src
, len
);
273 rb_strlcpy(char *dest
, const char *src
, size_t size
)
275 return strlcpy(dest
, src
, size
);
282 rb_strnlen(const char *s
, size_t count
)
285 for(sc
= s
; count
-- && *sc
!= '\0'; ++sc
)
291 rb_strnlen(const char *s
, size_t count
)
293 return strnlen(s
, count
);
298 * rb_snprintf_append()
299 * appends snprintf formatted string to the end of the buffer but not
303 rb_snprintf_append(char *str
, size_t len
, const char *format
, ...)
308 int orig_len
= strlen(str
);
310 if((int)len
< orig_len
)
317 va_start(ap
, format
);
318 int append_len
= vsnprintf(str
+ orig_len
, len
- orig_len
, format
, ap
);
324 return (orig_len
+ append_len
);
328 * rb_snprintf_try_append()
329 * appends snprintf formatted string to the end of the buffer but not
331 * returns -1 if there isn't enough space for the whole string to fit
334 rb_snprintf_try_append(char *str
, size_t len
, const char *format
, ...)
339 int orig_len
= strlen(str
);
341 if((int)len
< orig_len
) {
347 va_start(ap
, format
);
348 int append_len
= vsnprintf(str
+ orig_len
, len
- orig_len
, format
, ap
);
354 if (orig_len
+ append_len
> (int)(len
- 1)) {
355 str
[orig_len
] = '\0';
359 return (orig_len
+ append_len
);
369 rb_basename(const char *path
)
373 if(!(s
= strrchr(path
, '/')))
385 rb_dirname (const char *path
)
389 s
= strrchr(path
, '/');
392 return rb_strdup(".");
395 /* remove extra slashes */
396 while(s
> path
&& *s
== '/')
399 return rb_strndup(path
, ((uintptr_t)s
- (uintptr_t)path
) + 2);
404 int rb_fsnprint(char *buf
, size_t len
, const rb_strf_t
*strings
)
407 size_t remaining
= len
;
409 while (strings
!= NULL
) {
412 if (strings
->length
!= 0) {
413 remaining
= strings
->length
;
414 if (remaining
> len
- used
)
415 remaining
= len
- used
;
421 if (strings
->format
!= NULL
) {
422 if (strings
->format_args
!= NULL
) {
423 ret
= vsnprintf(buf
+ used
, remaining
,
424 strings
->format
, *strings
->format_args
);
426 ret
= rb_strlcpy(buf
+ used
,
427 strings
->format
, remaining
);
429 } else if (strings
->func
!= NULL
) {
430 ret
= strings
->func(buf
+ used
, remaining
,
436 } else if ((size_t)ret
> remaining
- 1) {
437 used
+= remaining
- 1;
442 if (used
>= len
- 1) {
448 strings
= strings
->next
;
454 int rb_fsnprintf(char *buf
, size_t len
, const rb_strf_t
*strings
, const char *format
, ...)
457 rb_strf_t prepend_string
= { .format
= format
, .format_args
= &args
, .next
= strings
};
460 va_start(args
, format
);
461 ret
= rb_fsnprint(buf
, len
, &prepend_string
);