2010-07-27 01:22:20 -07:00
|
|
|
/* EINA - EFL data type library
|
2010-08-02 02:43:57 -07:00
|
|
|
* Copyright (C) 2010 Tom Hacohen,
|
|
|
|
* Brett Nash
|
2010-07-27 01:22:20 -07:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Eina.h>
|
|
|
|
#include "eina_unicode.h"
|
|
|
|
|
|
|
|
/* FIXME: check if sizeof(wchar_t) == sizeof(Eina_Unicode) if so,
|
|
|
|
* probably better to use the standard functions */
|
|
|
|
|
2010-08-12 07:16:32 -07:00
|
|
|
/* Maybe I'm too tired, but this is the only thing that actually worked. */
|
|
|
|
const Eina_Unicode _EINA_UNICODE_EMPTY_STRING[1] = {0};
|
|
|
|
EAPI const Eina_Unicode *EINA_UNICODE_EMPTY_STRING = _EINA_UNICODE_EMPTY_STRING;
|
2010-07-27 01:22:20 -07:00
|
|
|
/**
|
|
|
|
* @brief Same as the standard strcmp just with Eina_Unicode instead of char.
|
|
|
|
*/
|
|
|
|
EAPI int
|
|
|
|
eina_unicode_strcmp(const Eina_Unicode *a, const Eina_Unicode *b)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
for (; *a && *a == *b; a++, b++)
|
2010-07-27 01:22:20 -07:00
|
|
|
;
|
|
|
|
if (*a == *b)
|
|
|
|
return 0;
|
|
|
|
else if (*a < *b)
|
|
|
|
return -1;
|
2010-07-27 19:37:05 -07:00
|
|
|
else
|
2010-07-27 01:22:20 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Same as the standard strcpy just with Eina_Unicode instead of char.
|
|
|
|
*/
|
|
|
|
EAPI Eina_Unicode *
|
|
|
|
eina_unicode_strcpy(Eina_Unicode *dest, const Eina_Unicode *source)
|
|
|
|
{
|
|
|
|
Eina_Unicode *ret = dest;
|
2010-07-27 19:37:05 -07:00
|
|
|
|
2010-07-27 01:22:20 -07:00
|
|
|
while (*source)
|
|
|
|
*dest++ = *source++;
|
2010-08-02 02:44:01 -07:00
|
|
|
*dest = 0;
|
2010-07-27 01:22:20 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Same as the standard strncpy just with Eina_Unicode instead of char.
|
|
|
|
*/
|
|
|
|
EAPI Eina_Unicode *
|
|
|
|
eina_unicode_strncpy(Eina_Unicode *dest, const Eina_Unicode *source, size_t n)
|
|
|
|
{
|
|
|
|
Eina_Unicode *ret = dest;
|
2010-07-27 19:37:05 -07:00
|
|
|
|
2010-08-02 02:44:11 -07:00
|
|
|
for ( ; n && *source ; n--)
|
2010-07-27 01:22:20 -07:00
|
|
|
*dest++ = *source++;
|
2010-07-27 19:37:05 -07:00
|
|
|
for (; n; n--)
|
2010-07-27 01:22:20 -07:00
|
|
|
*dest++ = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Same as the standard strlen just with Eina_Unicode instead of char.
|
|
|
|
*/
|
|
|
|
EAPI size_t
|
|
|
|
eina_unicode_strlen(const Eina_Unicode *ustr)
|
|
|
|
{
|
|
|
|
const Eina_Unicode *end;
|
2010-07-27 19:37:05 -07:00
|
|
|
for (end = ustr; *end; end++)
|
2010-07-27 01:22:20 -07:00
|
|
|
;
|
|
|
|
return end - ustr;
|
|
|
|
}
|
|
|
|
|
2010-07-29 20:39:12 -07:00
|
|
|
/**
|
|
|
|
* @brief Returns the length of a Eina_Unicode string, up to a limit.
|
|
|
|
*
|
|
|
|
* This function returns the number of characters in string, up to a maximum
|
|
|
|
* of n. If the terminating character is not found in the string, it returns
|
|
|
|
* n.
|
|
|
|
*
|
|
|
|
* @param ustr String to search
|
|
|
|
* @param n Max length to search
|
|
|
|
* @return Number of characters or n.
|
|
|
|
*/
|
|
|
|
EAPI size_t
|
|
|
|
eina_unicode_strnlen(const Eina_Unicode *ustr, int n)
|
|
|
|
{
|
|
|
|
const Eina_Unicode *end;
|
2010-07-30 20:54:09 -07:00
|
|
|
const Eina_Unicode *last = ustr + n; /* technically not portable ;-) */
|
2010-08-02 02:43:57 -07:00
|
|
|
for (end = ustr; end < last && *end; end++)
|
2010-07-29 20:39:12 -07:00
|
|
|
;
|
|
|
|
return end - ustr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-02-08 05:43:03 -08:00
|
|
|
/**
|
|
|
|
* @brief Same as strdup but cuts on n. Assumes n < len
|
|
|
|
* @since 1.1.0
|
|
|
|
*/
|
|
|
|
EAPI Eina_Unicode *
|
|
|
|
eina_unicode_strndup(const Eina_Unicode *text, size_t n)
|
|
|
|
{
|
|
|
|
Eina_Unicode *ustr;
|
|
|
|
|
|
|
|
ustr = (Eina_Unicode *) malloc((n + 1) * sizeof(Eina_Unicode));
|
|
|
|
memcpy(ustr, text, n * sizeof(Eina_Unicode));
|
|
|
|
ustr[n] = 0;
|
|
|
|
return ustr;
|
|
|
|
}
|
|
|
|
|
2010-07-27 01:22:20 -07:00
|
|
|
/**
|
|
|
|
* @brief Same as the standard strdup just with Eina_Unicode instead of char.
|
|
|
|
*/
|
|
|
|
EAPI Eina_Unicode *
|
|
|
|
eina_unicode_strdup(const Eina_Unicode *text)
|
|
|
|
{
|
2010-12-10 16:40:05 -08:00
|
|
|
size_t len;
|
2010-07-27 01:22:20 -07:00
|
|
|
|
|
|
|
len = eina_unicode_strlen(text);
|
2011-02-08 05:43:03 -08:00
|
|
|
return eina_unicode_strndup(text, len);
|
2010-07-27 01:22:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-12-29 23:51:26 -08:00
|
|
|
* @brief Same as the standard strstr just with Eina_Unicode instead of char.
|
2010-07-27 01:22:20 -07:00
|
|
|
*/
|
|
|
|
EAPI Eina_Unicode *
|
|
|
|
eina_unicode_strstr(const Eina_Unicode *haystack, const Eina_Unicode *needle)
|
|
|
|
{
|
|
|
|
const Eina_Unicode *i, *j;
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
for (i = haystack; *i; i++)
|
2010-07-27 01:22:20 -07:00
|
|
|
{
|
|
|
|
haystack = i; /* set this location as the base position */
|
2010-07-27 19:37:05 -07:00
|
|
|
for (j = needle; *j && *i && *j == *i; j++, i++)
|
2010-07-27 01:22:20 -07:00
|
|
|
;
|
|
|
|
|
|
|
|
if (!*j) /*if we got to the end of j this means we got a full match */
|
2010-07-27 20:03:25 -07:00
|
|
|
{
|
|
|
|
return (Eina_Unicode *)haystack; /* return the new base position */
|
|
|
|
}
|
2010-07-27 01:22:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see eina_str_escape()
|
|
|
|
*/
|
|
|
|
EAPI Eina_Unicode *
|
|
|
|
eina_unicode_escape(const Eina_Unicode *str)
|
|
|
|
{
|
|
|
|
Eina_Unicode *s2, *d;
|
|
|
|
const Eina_Unicode *s;
|
|
|
|
|
|
|
|
s2 = malloc((eina_unicode_strlen(str) * 2) + 1);
|
2010-07-27 19:37:05 -07:00
|
|
|
if (!s2)
|
|
|
|
return NULL;
|
|
|
|
|
2010-07-27 01:22:20 -07:00
|
|
|
for (s = str, d = s2; *s != 0; s++, d++)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
if ((*s == ' ') || (*s == '\\') || (*s == '\''))
|
|
|
|
{
|
|
|
|
*d = '\\';
|
|
|
|
d++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*d = *s;
|
2010-07-27 01:22:20 -07:00
|
|
|
}
|
|
|
|
*d = 0;
|
|
|
|
return s2;
|
|
|
|
}
|
|
|
|
|