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 str_len = strlen(str);
60 suffix_len = eina_strlen_bounded(suffix, str_len);
61 if (suffix_len == (size_t)-1)
64 return cmp(str + str_len - suffix_len, suffix) == 0;
68 eina_str_split_full_helper(const char *str,
71 unsigned int *elements)
89 /* count tokens and check strlen(str) */
92 const char *d = delim, *d_end = d + dlen;
93 const char *tmp = src;
94 for (; (d < d_end) && (*tmp != '\0'); d++, tmp++)
96 if (EINA_LIKELY(*d != *tmp))
99 if (EINA_UNLIKELY(d == d_end))
109 if ((max_tokens > 0) && (tokens > (unsigned int)max_tokens))
112 str_array = malloc(sizeof(char *) * (tokens + 2));
131 /* copy tokens and string */
137 const char *d = delim, *d_end = d + dlen;
138 const char *tmp = src;
139 for (; (d < d_end) && (*tmp != '\0'); d++, tmp++)
141 if (EINA_LIKELY(*d != *tmp))
144 if (EINA_UNLIKELY(d == d_end))
150 str_array[tokens] = s;
160 str_array[tokens + 1] = NULL;
162 *elements = (tokens + 1);
171 /*============================================================================*
173 *============================================================================*/
175 /*============================================================================*
177 *============================================================================*/
180 eina_strlcpy(char *dst, const char *src, size_t siz)
183 return strlcpy(dst, src, siz);
189 /* Copy as many bytes as will fit */
193 if ((*d++ = *s++) == '\0')
197 /* Not enough room in dst, add NUL and traverse rest of src */
201 *d = '\0'; /* NUL-terminate dst */
207 return(s - src - 1); /* count does not include NUL */
212 eina_strlcat(char *dst, const char *src, size_t siz)
219 /* Find the end of dst and adjust bytes left but don't go past end */
220 while (n-- != 0 && *d != '\0')
226 return(dlen + strlen(s));
239 return(dlen + (s - src)); /* count does not include NUL */
243 eina_str_has_prefix(const char *str, const char *prefix)
248 str_len = strlen(str);
249 prefix_len = eina_strlen_bounded(prefix, str_len);
250 if (prefix_len == (size_t)-1)
253 return (strncmp(str, prefix, prefix_len) == 0);
257 eina_str_has_suffix(const char *str, const char *suffix)
259 return eina_str_has_suffix_helper(str, suffix, strcmp);
263 eina_str_has_extension(const char *str, const char *ext)
265 return eina_str_has_suffix_helper(str, ext, strcasecmp);
269 eina_str_split_full(const char *str,
272 unsigned int *elements)
274 return eina_str_split_full_helper(str, delim, max_tokens, elements);
279 eina_str_split(const char *str, const char *delim, int max_tokens)
281 return eina_str_split_full_helper(str, delim, max_tokens, NULL);
285 eina_str_join_len(char *dst,
293 size_t ret = a_len + b_len + 1;
301 memcpy(dst, a, size - 1);
302 dst[size - 1] = '\0';
306 memcpy(dst, a, a_len);
311 dst[size - 1] = '\0';
318 if (size <= off + b_len + 1)
320 memcpy(dst + off, b, size - off - 1);
321 dst[size - 1] = '\0';
325 memcpy(dst + off, b, b_len);
326 dst[off + b_len] = '\0';
332 eina_str_convert(const char *enc_from, const char *enc_to, const char *text)
335 char *new_txt, *inp, *outp;
336 size_t inb, outb, outlen, tob, outalloc;
341 ic = iconv_open(enc_to, enc_from);
342 if (ic == (iconv_t)(-1))
345 new_txt = malloc(64);
358 count = iconv(ic, &inp, &inb, &outp, &outb);
359 outlen += tob - outb;
360 if (count == (size_t)(-1))
364 new_txt = realloc(new_txt, outalloc + 64);
365 outp = new_txt + outlen;
369 else if (errno == EILSEQ)
377 else if (errno == EINVAL)
397 if (outalloc == outlen)
398 new_txt = realloc(new_txt, outalloc + 1);
409 eina_str_convert(const char *enc_from __UNUSED__,
410 const char *enc_to __UNUSED__,
411 const char *text __UNUSED__)
418 eina_str_escape(const char *str)
423 s2 = malloc((strlen(str) * 2) + 1);
427 for (s = str, d = s2; *s != 0; s++, d++)
429 if ((*s == ' ') || (*s == '\\') || (*s == '\''))
442 eina_str_tolower(char **str)
445 if ((!str) || (!(*str)))
448 for (p = *str; (*p); p++)
449 *p = tolower((unsigned char )(*p));
453 eina_str_toupper(char **str)
456 if ((!str) || (!(*str)))
459 for (p = *str; (*p); p++)
460 *p = toupper((unsigned char)(*p));