1 /* Leave the OpenBSD version below so we can track upstream fixes */
2 /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
5 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
36 #include "eina_private.h"
39 /*============================================================================*
41 *============================================================================*/
48 * Internal helper function used by eina_str_has_suffix() and
49 * eina_str_has_extension()
51 static inline Eina_Bool
52 eina_str_has_suffix_helper(const char *str,
54 int (*cmp)(const char *, const char *))
59 if ((!str) || (!suffix)) return EINA_FALSE;
60 str_len = strlen(str);
61 suffix_len = eina_strlen_bounded(suffix, str_len);
62 if (suffix_len == (size_t)-1)
65 return cmp(str + str_len - suffix_len, suffix) == 0;
69 eina_str_split_full_helper(const char *str,
72 unsigned int *elements)
79 EINA_SAFETY_ON_TRUE_RETURN_VAL(max_tokens < 1, NULL);
91 /* count tokens and check strlen(str) */
94 const char *d = delim, *d_end = d + dlen;
95 const char *tmp = src;
96 for (; (d < d_end) && (*tmp != '\0'); d++, tmp++)
98 if (EINA_LIKELY(*d != *tmp))
101 if (EINA_UNLIKELY(d == d_end))
111 if ((max_tokens > 0) && (tokens > (unsigned int)max_tokens))
114 str_array = malloc(sizeof(char *) * (tokens + 2));
133 /* copy tokens and string */
139 const char *d = delim, *d_end = d + dlen;
140 const char *tmp = src;
141 for (; (d < d_end) && (*tmp != '\0'); d++, tmp++)
143 if (EINA_LIKELY(*d != *tmp))
146 if (EINA_UNLIKELY(d == d_end))
152 str_array[tokens] = s;
162 str_array[tokens + 1] = NULL;
164 *elements = (tokens + 1);
173 /*============================================================================*
175 *============================================================================*/
177 /*============================================================================*
179 *============================================================================*/
182 eina_strlcpy(char *dst, const char *src, size_t siz)
185 return strlcpy(dst, src, siz);
191 /* Copy as many bytes as will fit */
195 if ((*d++ = *s++) == '\0')
199 /* Not enough room in dst, add NUL and traverse rest of src */
203 *d = '\0'; /* NUL-terminate dst */
209 return(s - src - 1); /* count does not include NUL */
214 eina_strlcat(char *dst, const char *src, size_t siz)
221 /* Find the end of dst and adjust bytes left but don't go past end */
222 while (n-- != 0 && *d != '\0')
228 return(dlen + strlen(s));
241 return(dlen + (s - src)); /* count does not include NUL */
245 eina_str_has_prefix(const char *str, const char *prefix)
250 str_len = strlen(str);
251 prefix_len = eina_strlen_bounded(prefix, str_len);
252 if (prefix_len == (size_t)-1)
255 return (strncmp(str, prefix, prefix_len) == 0);
259 eina_str_has_suffix(const char *str, const char *suffix)
261 return eina_str_has_suffix_helper(str, suffix, strcmp);
265 eina_str_has_extension(const char *str, const char *ext)
267 return eina_str_has_suffix_helper(str, ext, strcasecmp);
271 eina_str_split_full(const char *str,
274 unsigned int *elements)
276 return eina_str_split_full_helper(str, delim, max_tokens, elements);
281 eina_str_split(const char *str, const char *delim, int max_tokens)
283 return eina_str_split_full_helper(str, delim, max_tokens, NULL);
287 eina_str_join_len(char *dst,
295 size_t ret = a_len + b_len + 1;
303 memcpy(dst, a, size - 1);
304 dst[size - 1] = '\0';
308 memcpy(dst, a, a_len);
313 dst[size - 1] = '\0';
320 if (size <= off + b_len + 1)
322 memcpy(dst + off, b, size - off - 1);
323 dst[size - 1] = '\0';
327 memcpy(dst + off, b, b_len);
328 dst[off + b_len] = '\0';
334 eina_str_convert(const char *enc_from, const char *enc_to, const char *text)
337 char *new_txt, *inp, *outp;
338 size_t inb, outb, outlen, tob, outalloc;
343 ic = iconv_open(enc_to, enc_from);
344 if (ic == (iconv_t)(-1))
347 new_txt = malloc(64);
360 count = iconv(ic, &inp, &inb, &outp, &outb);
361 outlen += tob - outb;
362 if (count == (size_t)(-1))
366 new_txt = realloc(new_txt, outalloc + 64);
367 outp = new_txt + outlen;
371 else if (errno == EILSEQ)
379 else if (errno == EINVAL)
399 if (outalloc == outlen)
400 new_txt = realloc(new_txt, outalloc + 1);
411 eina_str_convert(const char *enc_from __UNUSED__,
412 const char *enc_to __UNUSED__,
413 const char *text __UNUSED__)
420 eina_str_escape(const char *str)
425 s2 = malloc((strlen(str) * 2) + 1);
429 for (s = str, d = s2; *s != 0; s++, d++)
431 if ((*s == ' ') || (*s == '\\') || (*s == '\''))
444 eina_str_tolower(char **str)
447 if ((!str) || (!(*str)))
450 for (p = *str; (*p); p++)
451 *p = tolower((unsigned char )(*p));
455 eina_str_toupper(char **str)
458 if ((!str) || (!(*str)))
461 for (p = *str; (*p); p++)
462 *p = toupper((unsigned char)(*p));