efl/src/lib/eina/eina_str.c

735 lines
17 KiB
C
Raw Normal View History

/* Leave the OpenBSD version below so we can track upstream fixes */
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#ifdef HAVE_BSD_STRING_H
# include <bsd/string.h>
#endif
#ifdef HAVE_ICONV
# include <errno.h>
# include <iconv.h>
#endif
2010-01-30 14:02:08 -08:00
#include "eina_private.h"
#include "eina_str.h"
#include "eina_cpu.h"
/*============================================================================*
2010-07-27 19:37:05 -07:00
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
/*
* Internal helper function used by eina_str_has_suffix() and
* eina_str_has_extension()
*/
static inline Eina_Bool
eina_str_has_suffix_helper(const char *str,
2010-07-27 19:37:05 -07:00
const char *suffix,
int (*cmp)(const char *, const char *))
{
size_t str_len;
size_t suffix_len;
if ((!str) || (!suffix)) return EINA_FALSE;
str_len = strlen(str);
suffix_len = eina_strlen_bounded(suffix, str_len);
if (suffix_len == (size_t)-1)
2010-07-27 19:37:05 -07:00
return EINA_FALSE;
return cmp(str + str_len - suffix_len, suffix) == 0;
}
static inline char **
2010-07-27 19:37:05 -07:00
eina_str_split_full_helper(const char *str,
const char *delim,
int max_tokens,
unsigned int *elements)
{
char *s, *pos, **str_array;
const char *src;
size_t len, dlen;
unsigned int tokens = 0, x;
const char *idx[256] = {NULL};
if ((!str) || (!delim))
{
if (elements)
*elements = 0;
return NULL;
}
if (max_tokens < 0) max_tokens = 0;
if (max_tokens == 1)
{
str_array = malloc(sizeof(char *) * 2);
if (!str_array)
{
if (elements)
*elements = 0;
return NULL;
}
s = strdup(str);
if (!s)
{
free(str_array);
if (elements)
*elements = 0;
return NULL;
}
if (elements)
*elements = 1;
str_array[0] = s;
str_array[1] = NULL;
return str_array;
}
dlen = strlen(delim);
if (dlen == 0)
{
2010-07-27 19:37:05 -07:00
if (elements)
*elements = 0;
return NULL;
}
src = str;
/* count tokens and check strlen(str) */
while (*src != '\0')
{
2010-07-27 19:37:05 -07:00
const char *d = delim, *d_end = d + dlen;
const char *tmp = src;
for (; (d < d_end) && (*tmp != '\0'); d++, tmp++)
{
if (EINA_LIKELY(*d != *tmp))
break;
}
if (EINA_UNLIKELY(d == d_end))
{
src = tmp;
if (tokens < (sizeof(idx) / sizeof(idx[0])))
{
idx[tokens] = tmp;
//printf("token %d='%s'\n", tokens + 1, idx[tokens]);
}
2010-07-27 19:37:05 -07:00
tokens++;
if (tokens && (tokens == (unsigned int)max_tokens)) break;
2010-07-27 19:37:05 -07:00
}
else
src++;
}
len = src - str + strlen(src);
str_array = malloc(sizeof(char *) * (tokens + 2));
if (!str_array)
{
2010-07-27 19:37:05 -07:00
if (elements)
*elements = 0;
return NULL;
}
if (!tokens)
{
s = strdup(str);
if (!s)
{
free(str_array);
if (elements)
*elements = 0;
return NULL;
}
str_array[0] = s;
str_array[1] = NULL;
if (elements)
*elements = 1;
return str_array;
}
s = malloc(len + 1);
if (!s)
{
2010-07-27 19:37:05 -07:00
free(str_array);
if (elements)
*elements = 0;
return NULL;
}
str_array[0] = s;
if (len == tokens * dlen)
{
/* someone's having a laugh somewhere */
memset(s, 0, len + 1);
for (x = 1; x < tokens + 1; x++)
str_array[x] = s + x;
str_array[x] = NULL;
if (elements)
*elements = x;
return str_array;
}
/* copy tokens and string */
if (idx[0] - str - dlen > len)
{
/* FIXME: don't think this can happen but putting this here just in case */
abort();
}
pos = s;
for (x = 0; x < MIN(tokens, (sizeof(idx) / sizeof(idx[0]))); x++)
{
if (x + 1 < (sizeof(idx) / sizeof(idx[0])))
2010-07-27 19:37:05 -07:00
{
/* first one is special */
if (!x)
{
eina_strlcpy(pos, str, idx[x] - str - dlen + 1);
str_array[x] = pos;
//printf("str_array[%d] = '%s'\n", x, str_array[x]);
pos += idx[x] - str - dlen + 1;
if ((tokens == 1) && (idx[0]))
{
eina_strlcpy(pos, idx[x], len + 1 - (pos - s));
x++, tokens++;
str_array[x] = pos;
}
}
/* more tokens */
else if (idx[x + 1])
{
eina_strlcpy(pos, idx[x - 1], idx[x] - idx[x - 1] - dlen + 1);
str_array[x] = pos;
//printf("str_array[%d] = '%s'\n", x, str_array[x]);
pos += idx[x] - idx[x - 1] - dlen + 1;
}
/* last token */
else
{
if (max_tokens && ((unsigned int)max_tokens < tokens + 1))
eina_strlcpy(pos, idx[x - 1], len + 1 - (pos - s));
else
{
//printf("diff: %d\n", len + 1 - (pos - s));
eina_strlcpy(pos, idx[x - 1], idx[x] - idx[x - 1] - dlen + 1);
str_array[x] = pos;
//printf("str_array[%d] = '%s'\n", x, str_array[x]);
pos += idx[x] - idx[x - 1] - dlen + 1;
x++, tokens++;
eina_strlcpy(pos, idx[x - 1], len + 1 - (pos - s));
}
str_array[x] = pos;
//printf("str_array[%d] = '%s'\n", x, str_array[x]);
}
2010-07-27 19:37:05 -07:00
}
/* no more tokens saved after this one */
else
2010-07-27 19:37:05 -07:00
{
eina_strlcpy(pos, idx[x - 1], idx[x] - idx[x - 1] - dlen + 1);
str_array[x] = pos;
//printf("str_array[%d] = '%s'\n", x, str_array[x]);
pos += idx[x] - idx[x - 1] - dlen + 1;
src = idx[x];
x++, tokens++;
str_array[x] = s = pos;
break;
2010-07-27 19:37:05 -07:00
}
}
if ((x != tokens) && ((!max_tokens) || (x < tokens)))
{
while (*src != '\0')
2010-07-27 19:37:05 -07:00
{
const char *d = delim, *d_end = d + dlen;
const char *tmp = src;
for (; (d < d_end) && (*tmp != '\0'); d++, tmp++)
{
if (EINA_LIKELY(*d != *tmp))
break;
}
if (((!max_tokens) || (((tokens == (unsigned int)max_tokens) || x < tokens - 2))) && (EINA_UNLIKELY(d == d_end)))
{
src = tmp;
*s = '\0';
s++, x++;
//printf("str_array[%d] = '%s'\n", x, str_array[x - 1]);
str_array[x] = s;
}
else
{
*s = *src;
s++, src++;
}
2010-07-27 19:37:05 -07:00
}
*s = 0;
}
str_array[tokens] = NULL;
2010-07-27 19:37:05 -07:00
if (elements)
*elements = tokens;
2010-07-27 19:37:05 -07:00
return str_array;
}
/**
* @endcond
*/
/*============================================================================*
2010-07-27 19:37:05 -07:00
* Global *
*============================================================================*/
/*============================================================================*
2010-07-27 19:37:05 -07:00
* API *
*============================================================================*/
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API size_t
eina_strlcpy(char *dst, const char *src, size_t siz)
{
#ifdef HAVE_STRLCPY
return strlcpy(dst, src, siz);
#else
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0)
2010-07-27 19:37:05 -07:00
while (--n != 0)
{
if ((*d++ = *s++) == '\0')
break;
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0)
{
2010-07-27 19:37:05 -07:00
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
2010-07-27 19:37:05 -07:00
while (*s++)
;
}
2010-07-27 19:37:05 -07:00
return(s - src - 1); /* count does not include NUL */
#endif
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API size_t
eina_strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
2010-07-27 19:37:05 -07:00
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + (s ? strlen(s) : 0));
2010-07-27 19:37:05 -07:00
if (s != NULL)
{
while (*s != '\0') {
if (n != 1)
{
*d++ = *s;
n--;
}
s++;
}
2010-07-27 19:37:05 -07:00
}
*d = '\0';
2010-07-27 19:37:05 -07:00
return(dlen + (s - src)); /* count does not include NUL */
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char *
eina_strftime(const char *format, const struct tm *tm)
{
const size_t flen = strlen(format);
size_t buflen = 16; // An arbitrary starting size
char *buf = NULL;
do {
char *tmp;
size_t len;
tmp = realloc(buf, buflen * sizeof(char));
if (!tmp) goto on_error;
buf = tmp;
len = strftime(buf, buflen, format, tm);
// Check if we have the expected result and return it.
if ((len > 0 && len < buflen) || (len == 0 && flen == 0))
{
tmp = realloc(buf, ((len + 1) * sizeof(char)));
buf = tmp;
return buf;
}
/* Possibly buf overflowed - try again with a bigger buffer */
buflen <<= 1; // multiply buffer size by 2
} while (buflen < 128 * flen);
on_error:
free(buf);
return NULL;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_str_has_prefix(const char *str, const char *prefix)
{
size_t str_len;
size_t prefix_len;
str_len = strlen(str);
prefix_len = eina_strlen_bounded(prefix, str_len);
if (prefix_len == (size_t)-1)
2013-04-26 01:38:16 -07:00
return EINA_FALSE;
return (strncmp(str, prefix, prefix_len) == 0);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_str_has_suffix(const char *str, const char *suffix)
{
return eina_str_has_suffix_helper(str, suffix, strcmp);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API Eina_Bool
eina_str_has_extension(const char *str, const char *ext)
{
return eina_str_has_suffix_helper(str, ext, strcasecmp);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char **
2010-07-27 19:37:05 -07:00
eina_str_split_full(const char *str,
const char *delim,
int max_tokens,
unsigned int *elements)
{
return eina_str_split_full_helper(str, delim, max_tokens, elements);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char **
eina_str_split(const char *str, const char *delim, int max_tokens)
{
return eina_str_split_full_helper(str, delim, max_tokens, NULL);
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API size_t
2010-07-27 19:37:05 -07:00
eina_str_join_len(char *dst,
size_t size,
char sep,
const char *a,
size_t a_len,
const char *b,
size_t b_len)
{
size_t ret = a_len + b_len + 1;
size_t off;
2010-07-27 19:37:05 -07:00
if (size < 1)
2013-04-26 01:38:16 -07:00
return ret;
if (size <= a_len)
{
2010-07-27 19:37:05 -07:00
memcpy(dst, a, size - 1);
dst[size - 1] = '\0';
return ret;
}
2013-06-12 06:46:49 -07:00
memcpy(dst, a, a_len);
off = a_len;
if (size <= off + 1)
{
2010-07-27 19:37:05 -07:00
dst[size - 1] = '\0';
return ret;
}
dst[off] = sep;
off++;
if (size <= off + b_len + 1)
{
2010-07-27 19:37:05 -07:00
memcpy(dst + off, b, size - off - 1);
dst[size - 1] = '\0';
return ret;
}
2013-04-26 01:38:16 -07:00
memcpy(dst + off, b, b_len);
dst[off + b_len] = '\0';
return ret;
}
#ifdef HAVE_ICONV
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char *
eina_str_convert(const char *enc_from, const char *enc_to, const char *text)
{
iconv_t ic;
char *new_txt, *outp;
const char *inp;
size_t inb, outb, outlen, tob, outalloc;
2010-07-27 19:37:05 -07:00
if (!text)
return NULL;
ic = iconv_open(enc_to, enc_from);
2010-07-27 19:37:05 -07:00
if (ic == (iconv_t)(-1))
return NULL;
new_txt = malloc(64);
inb = strlen(text);
outb = 64;
inp = text;
2010-07-27 19:37:05 -07:00
outp = new_txt;
outalloc = 64;
2010-07-27 19:37:05 -07:00
outlen = 0;
2010-07-27 19:37:05 -07:00
for (;; )
{
2010-07-27 19:37:05 -07:00
size_t count;
tob = outb;
count = iconv(ic, (char **)&inp, &inb, &outp, &outb);
2010-07-27 19:37:05 -07:00
outlen += tob - outb;
if (count == (size_t)(-1))
{
if (errno == E2BIG)
{
new_txt = realloc(new_txt, outalloc + 64);
outp = new_txt + outlen;
outalloc += 64;
outb += 64;
}
else
{
if (new_txt)
free(new_txt);
new_txt = NULL;
break;
}
}
if (inb == 0)
{
if (outalloc == outlen)
new_txt = realloc(new_txt, outalloc + 1);
new_txt[outlen] = 0;
break;
}
}
iconv_close(ic);
return new_txt;
}
#else
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char *
eina_str_convert(const char *enc_from EINA_UNUSED,
const char *enc_to EINA_UNUSED,
const char *text EINA_UNUSED)
{
return NULL;
}
#endif
#ifdef HAVE_ICONV
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char *
eina_str_convert_len(const char *enc_from, const char *enc_to, const char *text, size_t len, size_t *retlen)
{
iconv_t ic;
char *new_txt, *outp;
const char *inp;
size_t inb, outb, outlen, tob, outalloc;
if (retlen) *retlen = 0;
if (!text) return NULL;
ic = iconv_open(enc_to, enc_from);
if (ic == (iconv_t)(-1))
return NULL;
new_txt = malloc(64);
inb = len;
outb = 64;
inp = text;
outp = new_txt;
outalloc = 64;
outlen = 0;
for (;; )
{
size_t count;
tob = outb;
count = iconv(ic, (char **)&inp, &inb, &outp, &outb);
outlen += tob - outb;
if (count == (size_t)(-1))
{
if (errno == E2BIG)
{
new_txt = realloc(new_txt, outalloc + 64);
outp = new_txt + outlen;
outalloc += 64;
outb += 64;
}
else
{
if (new_txt)
free(new_txt);
new_txt = NULL;
break;
}
}
if (inb == 0)
{
if (outalloc == outlen)
new_txt = realloc(new_txt, outalloc + 1);
new_txt[outlen] = 0;
break;
}
}
iconv_close(ic);
if (retlen) *retlen = outlen;
return new_txt;
}
#else
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char *
eina_str_convert_len(const char *enc_from EINA_UNUSED, const char *enc_to EINA_UNUSED, const char *text EINA_UNUSED, size_t len EINA_UNUSED, size_t *retlen)
{
if (retlen) *retlen = 0;
return NULL;
}
#endif
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API char *
eina_str_escape(const char *str)
{
char *s2, *d;
const char *s;
if (!str)
return NULL;
s2 = malloc((strlen(str) * 2) + 1);
2010-07-27 19:37:05 -07:00
if (!s2)
return NULL;
for (s = str, d = s2; *s != 0; s++, d++)
{
switch (*s)
{
case ' ':
case '\\':
case '\'':
case '\"':
{
2010-07-27 19:37:05 -07:00
*d = '\\';
d++;
*d = *s;
break;
}
case '\n':
{
*d = '\\'; d++;
*d = 'n';
break;
}
case '\t':
{
*d = '\\'; d++;
*d = 't';
break;
}
default:
{
*d = *s;
break;
}
}
}
*d = 0;
return s2;
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API void
eina_str_tolower(char **str)
{
char *p;
2010-07-27 19:37:05 -07:00
if ((!str) || (!(*str)))
return;
for (p = *str; (*p); p++)
*p = tolower((unsigned char )(*p));
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API void
eina_str_toupper(char **str)
{
char *p;
2010-07-27 19:37:05 -07:00
if ((!str) || (!(*str)))
return;
for (p = *str; (*p); p++)
*p = toupper((unsigned char)(*p));
}
eina: Rename EAPI macro to EINA_API in Eina library Summary: Patch from a series of patches to rename EAPI symbols to specific library DSOs. EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))` However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: jptiz, lucas, woohyun, vtorri, raster Reviewed By: jptiz, lucas, vtorri Subscribers: ProhtMeyhet, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12188
2020-11-25 04:35:48 -08:00
EINA_API unsigned char *
eina_memdup(unsigned char *mem, size_t size, Eina_Bool terminate)
{
unsigned char *ret;
if (!mem) return NULL;
terminate = !!terminate;
ret = malloc(size + terminate);
if (!ret) return NULL;
memcpy(ret, mem, size);
if (terminate)
ret[size] = 0;
return ret;
}