summaryrefslogtreecommitdiff
path: root/src/stdlib
diff options
context:
space:
mode:
authordewyatt <none@none>2010-07-13 15:05:45 -0400
committerdewyatt <none@none>2010-07-13 15:05:45 -0400
commit34d5cdc704ce4bd590bf61a8424ee224a8ebe9d4 (patch)
treec76a67a906f6d4919da3aff21c859cd9ec3aa664 /src/stdlib
parent7e8c791089cd7d284ed14e7668338700b491b58e (diff)
Added SDL_utf8strlcpy to copy at UTF-8 character boundaries.
Changed SDL_SendKeyboardText and SDL_SendEditingText to use SDL_utf8strlcpy.
Diffstat (limited to 'src/stdlib')
-rw-r--r--src/stdlib/SDL_string.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index d70f8666..b6839c1c 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -29,6 +29,21 @@
#define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F'))
#define SDL_islowerhex(X) (((X) >= 'a') && ((X) <= 'f'))
+#define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4)
+#define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF)
+
+int UTF8_TrailingBytes(unsigned char c)
+{
+ if (c >= 0xC0 && c<= 0xDF)
+ return 1;
+ else if (c >= 0xE0 && c <= 0xEF)
+ return 2;
+ else if (c >= 0xF0 && c <= 0xF4)
+ return 3;
+ else
+ return 0;
+}
+
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOL)
static size_t
SDL_ScanLong(const char *text, int radix, long *valuep)
@@ -362,6 +377,38 @@ SDL_strlcpy(char *dst, const char *src, size_t maxlen)
}
#endif
+size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
+{
+ size_t src_bytes = SDL_strlen(src);
+ size_t bytes = SDL_min(src_bytes, dst_bytes - 1);
+ int i = 0;
+ char trailing_bytes = 0;
+ if (bytes)
+ {
+ unsigned char c = (unsigned char)src[bytes - 1];
+ if (UTF8_IsLeadByte(c))
+ --bytes;
+ else if (UTF8_IsTrailingByte(c))
+ {
+ for (i = bytes - 1; i != 0; --i)
+ {
+ c = (unsigned char)src[i];
+ trailing_bytes = UTF8_TrailingBytes(c);
+ if (trailing_bytes)
+ {
+ if (bytes - i != trailing_bytes + 1)
+ bytes = i;
+
+ break;
+ }
+ }
+ }
+ SDL_memcpy(dst, src, bytes);
+ }
+ dst[bytes] = '\0';
+ return bytes;
+}
+
#ifndef HAVE_STRLCAT
size_t
SDL_strlcat(char *dst, const char *src, size_t maxlen)