aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2004-05-13 11:20:27 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2004-05-13 11:20:27 +0000
commitea4ac135ff6e5e1881e3ebe0e730bcf1223cfbe7 (patch)
tree18cf76677a9cfe230068951dd5933888ea573d26 /lib
parent33e48d06ba79e43b5126ddde5abf21fa7b21b1e2 (diff)
downloadsrc-ea4ac135ff6e5e1881e3ebe0e730bcf1223cfbe7.tar.gz
src-ea4ac135ff6e5e1881e3ebe0e730bcf1223cfbe7.zip
Allow encoding modules to override the default implementations of
mbsrtowcs() and wcsrtombs(). Provide a fast implementation for the trivial "NONE" encoding.
Notes
Notes: svn path=/head/; revision=129179
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/locale/mblocal.h13
-rw-r--r--lib/libc/locale/mbsrtowcs.c12
-rw-r--r--lib/libc/locale/mbstowcs.c3
-rw-r--r--lib/libc/locale/none.c57
-rw-r--r--lib/libc/locale/setrunelocale.c18
-rw-r--r--lib/libc/locale/table.c4
-rw-r--r--lib/libc/locale/wcsrtombs.c12
-rw-r--r--lib/libc/locale/wcstombs.c3
8 files changed, 113 insertions, 9 deletions
diff --git a/lib/libc/locale/mblocal.h b/lib/libc/locale/mblocal.h
index c42870471c33..8e36ad5ea2a2 100644
--- a/lib/libc/locale/mblocal.h
+++ b/lib/libc/locale/mblocal.h
@@ -37,7 +37,11 @@
extern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict,
size_t, mbstate_t * __restrict);
extern int (*__mbsinit)(const mbstate_t *);
+extern size_t (*__mbsrtowcs)(wchar_t * __restrict, const char ** __restrict,
+ size_t, mbstate_t * __restrict);
extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict);
+extern size_t (*__wcsrtombs)(char * __restrict, const wchar_t ** __restrict,
+ size_t, mbstate_t * __restrict);
/*
* Conversion functions for "NONE"/C/POSIX encoding.
@@ -45,8 +49,17 @@ extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict);
extern size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict,
size_t, mbstate_t * __restrict);
extern int _none_mbsinit(const mbstate_t *);
+extern size_t _none_mbsrtowcs(wchar_t * __restrict, const char ** __restrict,
+ size_t, mbstate_t * __restrict);
extern size_t _none_wcrtomb(char * __restrict, wchar_t,
mbstate_t * __restrict);
+extern size_t _none_wcsrtombs(char * __restrict, const wchar_t ** __restrict,
+ size_t, mbstate_t * __restrict);
+
+extern size_t __mbsrtowcs_std(wchar_t * __restrict, const char ** __restrict,
+ size_t, mbstate_t * __restrict);
+extern size_t __wcsrtombs_std(char * __restrict, const wchar_t ** __restrict,
+ size_t, mbstate_t * __restrict);
/*
* Rune emulation functions.
diff --git a/lib/libc/locale/mbsrtowcs.c b/lib/libc/locale/mbsrtowcs.c
index 6a0f3e8d5851..a90c65563f7a 100644
--- a/lib/libc/locale/mbsrtowcs.c
+++ b/lib/libc/locale/mbsrtowcs.c
@@ -38,6 +38,16 @@ mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
mbstate_t * __restrict ps)
{
static mbstate_t mbs;
+
+ if (ps == NULL)
+ ps = &mbs;
+ return (__mbsrtowcs(dst, src, len, ps));
+}
+
+size_t
+__mbsrtowcs_std(wchar_t * __restrict dst, const char ** __restrict src,
+ size_t len, mbstate_t * __restrict ps)
+{
const char *s;
size_t nchr;
wchar_t wc;
@@ -46,8 +56,6 @@ mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
s = *src;
nchr = 0;
- if (ps == NULL)
- ps = &mbs;
if (dst == NULL) {
for (;;) {
if ((nb = (int)__mbrtowc(&wc, s, MB_CUR_MAX, ps)) < 0)
diff --git a/lib/libc/locale/mbstowcs.c b/lib/libc/locale/mbstowcs.c
index 1a05c7bf7baa..4623535457dd 100644
--- a/lib/libc/locale/mbstowcs.c
+++ b/lib/libc/locale/mbstowcs.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <wchar.h>
+#include "mblocal.h"
size_t
mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
@@ -37,5 +38,5 @@ mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
mbstate_t mbs;
mbs = initial;
- return (mbsrtowcs(pwcs, &s, n, &mbs));
+ return (__mbsrtowcs(pwcs, &s, n, &mbs));
}
diff --git a/lib/libc/locale/none.c b/lib/libc/locale/none.c
index c8b3874026df..6ac9a9e2712a 100644
--- a/lib/libc/locale/none.c
+++ b/lib/libc/locale/none.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <wchar.h>
#include "mblocal.h"
@@ -54,7 +55,11 @@ int _none_init(_RuneLocale *);
size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict);
int _none_mbsinit(const mbstate_t *);
+size_t _none_mbsrtowcs(wchar_t * __restrict, const char ** __restrict,
+ size_t, mbstate_t * __restrict);
size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict);
+size_t _none_wcsrtombs(char * __restrict, const wchar_t ** __restrict,
+ size_t, mbstate_t * __restrict);
int
_none_init(_RuneLocale *rl)
@@ -62,7 +67,9 @@ _none_init(_RuneLocale *rl)
__mbrtowc = _none_mbrtowc;
__mbsinit = _none_mbsinit;
+ __mbsrtowcs = _none_mbsrtowcs;
__wcrtomb = _none_wcrtomb;
+ __wcsrtombs = _none_wcsrtombs;
_CurrentRuneLocale = rl;
__mb_cur_max = 1;
return(0);
@@ -110,3 +117,53 @@ _none_wcrtomb(char * __restrict s, wchar_t wc,
*s = (unsigned char)wc;
return (1);
}
+
+size_t
+_none_mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src,
+ size_t len, mbstate_t * __restrict ps __unused)
+{
+ const char *s;
+ size_t nchr;
+
+ if (dst == NULL)
+ return (strlen(*src));
+
+ s = *src;
+ nchr = 0;
+ while (len-- > 0) {
+ if ((*dst++ = (unsigned char)*s++) == L'\0') {
+ *src = NULL;
+ return (nchr);
+ }
+ nchr++;
+ }
+ *src = s;
+ return (nchr);
+}
+
+size_t
+_none_wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src,
+ size_t len, mbstate_t * __restrict ps __unused)
+{
+ const wchar_t *s;
+ size_t nchr;
+
+ if (dst == NULL)
+ return (wcslen(*src));
+
+ s = *src;
+ nchr = 0;
+ while (len-- > 0) {
+ if (*s < 0 || *s > UCHAR_MAX) {
+ errno = EILSEQ;
+ return ((size_t)-1);
+ }
+ if ((*dst++ = *s++) == '\0') {
+ *src = NULL;
+ return (nchr);
+ }
+ nchr++;
+ }
+ *src = s;
+ return (nchr);
+}
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
index 4055ffe6b8cf..85b17a101457 100644
--- a/lib/libc/locale/setrunelocale.c
+++ b/lib/libc/locale/setrunelocale.c
@@ -100,6 +100,10 @@ __setrunelocale(const char *encoding)
static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t,
mbstate_t * __restrict);
static int (*Cached__mbsinit)(const mbstate_t *);
+ static size_t (*Cached__mbsrtowcs)(wchar_t * __restrict,
+ const char ** __restrict, size_t, mbstate_t * __restrict);
+ static size_t (*Cached__wcsrtombs)(char * __restrict,
+ const wchar_t ** __restrict, size_t, mbstate_t * __restrict);
/*
* The "C" and "POSIX" locale are always here.
@@ -108,8 +112,10 @@ __setrunelocale(const char *encoding)
_CurrentRuneLocale = &_DefaultRuneLocale;
__mb_cur_max = 1;
__mbrtowc = _none_mbrtowc;
- __wcrtomb = _none_wcrtomb;
__mbsinit = _none_mbsinit;
+ __mbsrtowcs = _none_mbsrtowcs;
+ __wcrtomb = _none_wcrtomb;
+ __wcsrtombs = _none_wcsrtombs;
return (0);
}
@@ -121,8 +127,10 @@ __setrunelocale(const char *encoding)
_CurrentRuneLocale = CachedRuneLocale;
__mb_cur_max = Cached__mb_cur_max;
__mbrtowc = Cached__mbrtowc;
- __wcrtomb = Cached__wcrtomb;
__mbsinit = Cached__mbsinit;
+ __mbsrtowcs = Cached__mbsrtowcs;
+ __wcrtomb = Cached__wcrtomb;
+ __wcsrtombs = Cached__wcsrtombs;
return (0);
}
@@ -147,8 +155,10 @@ __setrunelocale(const char *encoding)
(void)fclose(fp);
__mbrtowc = NULL;
- __wcrtomb = NULL;
__mbsinit = NULL;
+ __mbsrtowcs = __mbsrtowcs_std;
+ __wcrtomb = NULL;
+ __wcsrtombs = __wcsrtombs_std;
rl->sputrune = __emulated_sputrune;
rl->sgetrune = __emulated_sgetrune;
if (strcmp(rl->encoding, "NONE") == 0)
@@ -182,7 +192,9 @@ __setrunelocale(const char *encoding)
Cached__mb_cur_max = __mb_cur_max;
Cached__mbrtowc = __mbrtowc;
Cached__mbsinit = __mbsinit;
+ Cached__mbsrtowcs = __mbsrtowcs;
Cached__wcrtomb = __wcrtomb;
+ Cached__wcsrtombs = __wcsrtombs;
(void)strcpy(ctype_encoding, encoding);
} else
free(rl);
diff --git a/lib/libc/locale/table.c b/lib/libc/locale/table.c
index f8b8497048f7..4d72959505b3 100644
--- a/lib/libc/locale/table.c
+++ b/lib/libc/locale/table.c
@@ -255,5 +255,9 @@ int __mb_cur_max = 1;
size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict) = _none_mbrtowc;
int (*__mbsinit)(const mbstate_t *) = _none_mbsinit;
+size_t (*__mbsrtowcs)(wchar_t * __restrict, const char ** __restrict,
+ size_t, mbstate_t * __restrict) = _none_mbsrtowcs;
size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) =
_none_wcrtomb;
+size_t (*__wcsrtombs)(char * __restrict, const wchar_t ** __restrict,
+ size_t, mbstate_t * __restrict) = _none_wcsrtombs;
diff --git a/lib/libc/locale/wcsrtombs.c b/lib/libc/locale/wcsrtombs.c
index dfc541f36ce4..a03f0d33f83d 100644
--- a/lib/libc/locale/wcsrtombs.c
+++ b/lib/libc/locale/wcsrtombs.c
@@ -38,6 +38,16 @@ wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
mbstate_t * __restrict ps)
{
static mbstate_t mbs;
+
+ if (ps == NULL)
+ ps = &mbs;
+ return (__wcsrtombs(dst, src, len, ps));
+}
+
+size_t
+__wcsrtombs_std(char * __restrict dst, const wchar_t ** __restrict src,
+ size_t len, mbstate_t * __restrict ps)
+{
mbstate_t mbsbak;
char buf[MB_LEN_MAX];
const wchar_t *s;
@@ -47,8 +57,6 @@ wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
s = *src;
nbytes = 0;
- if (ps == NULL)
- ps = &mbs;
if (dst == NULL) {
for (;;) {
if ((nb = (int)__wcrtomb(buf, *s, ps)) < 0)
diff --git a/lib/libc/locale/wcstombs.c b/lib/libc/locale/wcstombs.c
index 79ee279227db..5bb5954a7cde 100644
--- a/lib/libc/locale/wcstombs.c
+++ b/lib/libc/locale/wcstombs.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <wchar.h>
+#include "mblocal.h"
size_t
wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
@@ -37,5 +38,5 @@ wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
mbstate_t mbs;
mbs = initial;
- return (wcsrtombs(s, &pwcs, n, &mbs));
+ return (__wcsrtombs(s, &pwcs, n, &mbs));
}