diff options
author | Tim J. Robbins <tjr@FreeBSD.org> | 2004-05-13 11:20:27 +0000 |
---|---|---|
committer | Tim J. Robbins <tjr@FreeBSD.org> | 2004-05-13 11:20:27 +0000 |
commit | ea4ac135ff6e5e1881e3ebe0e730bcf1223cfbe7 (patch) | |
tree | 18cf76677a9cfe230068951dd5933888ea573d26 /lib/libc/locale | |
parent | 33e48d06ba79e43b5126ddde5abf21fa7b21b1e2 (diff) |
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/libc/locale')
-rw-r--r-- | lib/libc/locale/mblocal.h | 13 | ||||
-rw-r--r-- | lib/libc/locale/mbsrtowcs.c | 12 | ||||
-rw-r--r-- | lib/libc/locale/mbstowcs.c | 3 | ||||
-rw-r--r-- | lib/libc/locale/none.c | 57 | ||||
-rw-r--r-- | lib/libc/locale/setrunelocale.c | 18 | ||||
-rw-r--r-- | lib/libc/locale/table.c | 4 | ||||
-rw-r--r-- | lib/libc/locale/wcsrtombs.c | 12 | ||||
-rw-r--r-- | lib/libc/locale/wcstombs.c | 3 |
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)); } |