summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale/utf2.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-04-07 10:48:19 +0000
committertjr <tjr@FreeBSD.org>2004-04-07 10:48:19 +0000
commit54a18fa1d63375b790f3bf3157f6b64b294e5d16 (patch)
tree44e2a3f83138ea23f4b4f68cbea18e4f60c8745e /lib/libc/locale/utf2.c
parenta6980b04fc41a4c6dc314dc3aa00de7e7834ba7b (diff)
downloadFreeBSD-src-54a18fa1d63375b790f3bf3157f6b64b294e5d16.zip
FreeBSD-src-54a18fa1d63375b790f3bf3157f6b64b294e5d16.tar.gz
Allow partial multibyte characters to accumulate in conversion state
objects passed to mbrtowc(), mbsrtowcs(), and mbrlen(), as required by C99.
Diffstat (limited to 'lib/libc/locale/utf2.c')
-rw-r--r--lib/libc/locale/utf2.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/lib/libc/locale/utf2.c b/lib/libc/locale/utf2.c
index 39befd6..af7cc2f 100644
--- a/lib/libc/locale/utf2.c
+++ b/lib/libc/locale/utf2.c
@@ -36,23 +36,29 @@
/* UTF2 is obsolete and will be removed in FreeBSD 6 -- use UTF-8 instead. */
#define OBSOLETE_IN_6
-#include <sys/cdefs.h>
+#include <sys/param.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <runetype.h>
-#include <stddef.h>
-#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <wchar.h>
extern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict,
size_t, mbstate_t * __restrict);
+extern int (*__mbsinit)(const mbstate_t *);
extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict);
-size_t _UTF2_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t,
+size_t _UTF2_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict);
-size_t _UTF2_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict);
+int _UTF2_mbsinit(const mbstate_t *);
+size_t _UTF2_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict);
+
+typedef struct {
+ int count;
+ u_char bytes[3];
+} _UTF2State;
int
_UTF2_init(_RuneLocale *rl)
@@ -60,21 +66,44 @@ _UTF2_init(_RuneLocale *rl)
__mbrtowc = _UTF2_mbrtowc;
__wcrtomb = _UTF2_wcrtomb;
+ __mbsinit = _UTF2_mbsinit;
_CurrentRuneLocale = rl;
__mb_cur_max = 3;
return (0);
}
+int
+_UTF2_mbsinit(const mbstate_t *ps)
+{
+
+ return (ps == NULL || ((_UTF2State *)ps)->count == 0);
+}
+
size_t
_UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
- mbstate_t * __restrict ps __unused)
+ mbstate_t * __restrict ps)
{
- int ch, i, len, mask;
+ _UTF2State *us;
+ int ch, i, len, mask, ocount;
wchar_t wch;
+ size_t ncopy;
+
+ us = (_UTF2State *)ps;
+
+ if (s == NULL) {
+ s = "";
+ n = 1;
+ pwc = NULL;
+ }
+
+ ncopy = MIN(MIN(n, MB_CUR_MAX), sizeof(us->bytes) - us->count);
+ memcpy(us->bytes + us->count, s, ncopy);
+ ocount = us->count;
+ us->count += ncopy;
+ s = (char *)us->bytes;
+ n = us->count;
- if (s == NULL)
- return (0);
if (n == 0)
return ((size_t)-2);
@@ -108,7 +137,8 @@ _UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n,
}
if (pwc != NULL)
*pwc = wch;
- return (wch == L'\0' ? 0 : len);
+ us->count = 0;
+ return (wch == L'\0' ? 0 : len - ocount);
}
size_t
@@ -119,6 +149,7 @@ _UTF2_wcrtomb(char * __restrict s, wchar_t wc,
int i, len;
if (s == NULL)
+ /* Reset to initial conversion state. */
return (1);
if ((wc & ~0x7f) == 0) {
OpenPOWER on IntegriCloud