diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-04-19 11:34:35 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-06-07 00:49:08 +0000 |
commit | eda3ef2de2d15b389090f6ef953edaea3daaace4 (patch) | |
tree | 0b56560d5acc9cedb2dae078f5398d84158e546d /usr/src/lib/libc | |
parent | e214b19eaa16fec1fa60a97227778103f598336f (diff) | |
download | illumos-joyent-eda3ef2de2d15b389090f6ef953edaea3daaace4.tar.gz |
12689 Want c11 uchar.h
Reviewed by: Yuri Pankov <ypankov@tintri.com>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/amd64/Makefile | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/Makefile.com | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/big5.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/c16rtomb.c | 78 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/c32rtomb.c | 50 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/euc.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/gb18030.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/gb2312.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/gbk.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/mblocal.h | 58 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/mbrtoc16.c | 91 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/mbrtoc32.c | 46 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/mbsinit.c | 18 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/mskanji.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/unicode.h | 68 | ||||
-rw-r--r-- | usr/src/lib/libc/port/locale/utf8.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 8 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile.com | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/Makefile.com | 4 |
19 files changed, 433 insertions, 36 deletions
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index 25ae31284c..d1e6809d83 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -747,6 +747,8 @@ PORTI18N_COND= \ PORTLOCALE= \ big5.o \ btowc.o \ + c16rtomb.o \ + c32rtomb.o \ collate.o \ collcmp.o \ euc.o \ @@ -772,6 +774,8 @@ PORTLOCALE= \ mbftowc.o \ mblen.o \ mbrlen.o \ + mbrtoc16.o \ + mbrtoc32.o \ mbrtowc.o \ mbsinit.o \ mbsnrtowcs.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 17bd421383..526c2fbc6f 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -794,6 +794,8 @@ PORTI18N_COND= \ PORTLOCALE= \ big5.o \ btowc.o \ + c16rtomb.o \ + c32rtomb.o \ collate.o \ collcmp.o \ euc.o \ @@ -819,6 +821,8 @@ PORTLOCALE= \ mbftowc.o \ mblen.o \ mbrlen.o \ + mbrtoc16.o \ + mbrtoc32.o \ mbrtowc.o \ mbsinit.o \ mbsnrtowcs.o \ diff --git a/usr/src/lib/libc/port/locale/big5.c b/usr/src/lib/libc/port/locale/big5.c index 889b182de5..53b3a31f59 100644 --- a/usr/src/lib/libc/port/locale/big5.c +++ b/usr/src/lib/libc/port/locale/big5.c @@ -55,10 +55,6 @@ static size_t _BIG5_wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD); -typedef struct { - wchar_t ch; -} _BIG5State; - void _BIG5_init(struct lc_ctype *lct) { diff --git a/usr/src/lib/libc/port/locale/c16rtomb.c b/usr/src/lib/libc/port/locale/c16rtomb.c new file mode 100644 index 0000000000..050f06206e --- /dev/null +++ b/usr/src/lib/libc/port/locale/c16rtomb.c @@ -0,0 +1,78 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Robert Mustacchi + */ + +/* + * C11 c16rtomb(3C) support. + * + * Convert a series of char16_t values into a series of multi-byte characters. + * We may be given a surrogate value, so we need to potentially store that in + * the interim. + */ + +#include <uchar.h> +#include <errno.h> +#include "mblocal.h" +#include "unicode.h" + +static mbstate_t c16rtomb_state; + +size_t +c16rtomb(char *restrict str, char16_t c16, mbstate_t *restrict ps) +{ + char32_t c32; + _CHAR16State *c16s; + + if (ps == NULL) { + ps = &c16rtomb_state; + } + + if (str == NULL) { + c16 = L'\0'; + } + + c16s = (_CHAR16State *)ps; + if (c16s->c16_surrogate != 0) { + if (c16 > UNICODE_SUR_MAX || c16 < UNICODE_SUR_MIN || + (c16 & UNICODE_SUR_LOWER) != UNICODE_SUR_LOWER) { + errno = EILSEQ; + return ((size_t)-1); + } + + c32 = UNICODE_SUR_UVALUE(c16s->c16_surrogate) | + UNICODE_SUR_LVALUE(c16); + c32 += UNICODE_SUP_START; + c16s->c16_surrogate = 0; + } else if (c16 >= UNICODE_SUR_MIN && c16 <= UNICODE_SUR_MAX) { + /* + * The lower surrogate pair mask (dc00) overlaps the upper mask + * (d800), hence why we do a binary and with the upper mask. + */ + if ((c16 & UNICODE_SUR_LOWER) != UNICODE_SUR_UPPER) { + errno = EILSEQ; + return ((size_t)-1); + } + + c16s->c16_surrogate = c16; + return (0); + } else { + c32 = c16; + } + + /* + * Call c32rtomb() and not wcrtomb() so that way all of the unicode code + * point validation is performed. + */ + return (c32rtomb(str, c32, ps)); +} diff --git a/usr/src/lib/libc/port/locale/c32rtomb.c b/usr/src/lib/libc/port/locale/c32rtomb.c new file mode 100644 index 0000000000..a4d7a591f1 --- /dev/null +++ b/usr/src/lib/libc/port/locale/c32rtomb.c @@ -0,0 +1,50 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Robert Mustacchi + */ + +/* + * C11 c32rtomb(3C) support. + * + * The char32_t type is designed to represent a UTF-32 value, which is what we + * can represent with a wchar_t. This is basically a wrapper around wcrtomb(). + */ + +#include <locale.h> +#include <wchar.h> +#include <xlocale.h> +#include <uchar.h> +#include <errno.h> +#include "unicode.h" + +static mbstate_t c32rtomb_state; + +size_t +c32rtomb(char *restrict str, char32_t c32, mbstate_t *restrict ps) +{ + if ((c32 >= UNICODE_SUR_MIN && c32 <= UNICODE_SUR_MAX) || + c32 > UNICODE_SUP_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + + if (ps == NULL) { + ps = &c32rtomb_state; + } + + if (str == NULL) { + c32 = L'\0'; + } + + return (wcrtomb_l(str, (wchar_t)c32, ps, uselocale((locale_t)0))); +} diff --git a/usr/src/lib/libc/port/locale/euc.c b/usr/src/lib/libc/port/locale/euc.c index 1d1d25b17b..97c7bc3bea 100644 --- a/usr/src/lib/libc/port/locale/euc.c +++ b/usr/src/lib/libc/port/locale/euc.c @@ -101,12 +101,6 @@ static size_t _EUC_TW_wcsnrtombs(char *_RESTRICT_KYWD, static int _EUC_mbsinit(const mbstate_t *); -typedef struct { - wchar_t ch; - int set; - int want; -} _EucState; - int _EUC_mbsinit(const mbstate_t *ps) { diff --git a/usr/src/lib/libc/port/locale/gb18030.c b/usr/src/lib/libc/port/locale/gb18030.c index 36c48c5cc5..3901270a8d 100644 --- a/usr/src/lib/libc/port/locale/gb18030.c +++ b/usr/src/lib/libc/port/locale/gb18030.c @@ -55,12 +55,6 @@ static size_t _GB18030_wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD); - -typedef struct { - int count; - uchar_t bytes[4]; -} _GB18030State; - void _GB18030_init(struct lc_ctype *lct) { diff --git a/usr/src/lib/libc/port/locale/gb2312.c b/usr/src/lib/libc/port/locale/gb2312.c index bfb6c0177b..9b42060d10 100644 --- a/usr/src/lib/libc/port/locale/gb2312.c +++ b/usr/src/lib/libc/port/locale/gb2312.c @@ -50,12 +50,6 @@ static size_t _GB2312_wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD); - -typedef struct { - int count; - uchar_t bytes[2]; -} _GB2312State; - void _GB2312_init(struct lc_ctype *lct) { diff --git a/usr/src/lib/libc/port/locale/gbk.c b/usr/src/lib/libc/port/locale/gbk.c index f422ce8fb5..6202091f87 100644 --- a/usr/src/lib/libc/port/locale/gbk.c +++ b/usr/src/lib/libc/port/locale/gbk.c @@ -55,10 +55,6 @@ static size_t _GBK_wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD); -typedef struct { - wchar_t ch; -} _GBKState; - void _GBK_init(struct lc_ctype *lct) { diff --git a/usr/src/lib/libc/port/locale/mblocal.h b/usr/src/lib/libc/port/locale/mblocal.h index 3d958e364e..2873962944 100644 --- a/usr/src/lib/libc/port/locale/mblocal.h +++ b/usr/src/lib/libc/port/locale/mblocal.h @@ -31,6 +31,64 @@ #include "runetype.h" #include "lctype.h" +#include <uchar.h> + +/* + * Actual implementation structures for mbstate_t data. + * + * All of the conversion states are independent of one another, with the + * exception of that used for mbrtoc16(). That needs to encode data not as a + * wide-character but as UTF-16 data, which means handling surrogate pairs. To + * minimize the amount of state in each locale, we instead have a conversion + * state for this which includes all the other conversion states, plus extra + * data to accomodate this. + */ +typedef struct { + wchar_t ch; +} _BIG5State; + +typedef struct { + wchar_t ch; + int set; + int want; +} _EucState; + +typedef struct { + int count; + uchar_t bytes[4]; +} _GB18030State; + +typedef struct { + int count; + uchar_t bytes[2]; +} _GB2312State; + +typedef struct { + wchar_t ch; +} _GBKState; + +typedef struct { + wchar_t ch; +} _MSKanjiState; + +typedef struct { + wchar_t ch; + int want; + wchar_t lbound; +} _UTF8State; + +typedef struct { + union { + _BIG5State c16_big5; + _EucState c16_euc; + _GB18030State c16_gb18030; + _GB2312State c16_gb2312; + _GBKState c16_gbk; + _MSKanjiState c16_mskanji; + _UTF8State c16_utf8; + } c16_state; + char16_t c16_surrogate; +} _CHAR16State; /* * Rune initialization function prototypes. diff --git a/usr/src/lib/libc/port/locale/mbrtoc16.c b/usr/src/lib/libc/port/locale/mbrtoc16.c new file mode 100644 index 0000000000..a8e6e8119b --- /dev/null +++ b/usr/src/lib/libc/port/locale/mbrtoc16.c @@ -0,0 +1,91 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Robert Mustacchi + */ + +/* + * C11 mbrtoc16(3C) support. + * + * The char16_t represents a UTF-16 encoding. This means that we have to deal + * with surrogate pairs. + */ + +#include <locale.h> +#include <wchar.h> +#include <xlocale.h> +#include <uchar.h> +#include "mblocal.h" +#include "unicode.h" + +#include <sys/debug.h> + +/* + * Ensure that we never cause our save state to ever exceed that of the + * mbstate_t. See the block comment in mblocal.h. + */ +CTASSERT(sizeof (_CHAR16State) <= sizeof (mbstate_t)); + +static mbstate_t mbrtoc16_state; + +size_t +mbrtoc16(char16_t *restrict pc16, const char *restrict str, size_t len, + mbstate_t *restrict ps) +{ + wchar_t wc; + size_t ret; + char16_t out; + _CHAR16State *c16s; + + if (ps == NULL) { + ps = &mbrtoc16_state; + } + + if (str == NULL) { + pc16 = NULL; + str = ""; + len = 1; + } + + c16s = (_CHAR16State *)ps; + if (c16s->c16_surrogate != 0) { + if (pc16 != NULL) { + *pc16 = c16s->c16_surrogate; + } + c16s->c16_surrogate = 0; + return ((size_t)-3); + } + + ret = mbrtowc_l(&wc, str, len, ps, uselocale(NULL)); + if ((ssize_t)ret < 0) { + return (ret); + } + + /* + * If this character is not in the basic multilingual plane then we need + * a surrogate character to represent it in UTF-16 and we will need to + * write that out on the next iteration. + */ + if (wc >= UNICODE_SUP_START) { + wc -= UNICODE_SUP_START; + c16s->c16_surrogate = UNICODE_SUR_LOWER | UNICODE_SUR_LMASK(wc); + out = UNICODE_SUR_UPPER | UNICODE_SUR_UMASK(wc); + } else { + out = (char16_t)wc; + } + + if (pc16 != NULL) { + *pc16 = out; + } + + return (ret); +} diff --git a/usr/src/lib/libc/port/locale/mbrtoc32.c b/usr/src/lib/libc/port/locale/mbrtoc32.c new file mode 100644 index 0000000000..46df3fb1f0 --- /dev/null +++ b/usr/src/lib/libc/port/locale/mbrtoc32.c @@ -0,0 +1,46 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Robert Mustacchi + */ + +/* + * C11 mbrtoc32(3C) support. + * + * The char32_t type is designed to represent UTF-32. Conveniently, the wchar_t + * is as well. In this case, we can just pass this directly to mbrtowc_l(). + */ + +#include <locale.h> +#include <wchar.h> +#include <xlocale.h> +#include <uchar.h> + +static mbstate_t mbrtoc32_state; + +size_t +mbrtoc32(char32_t *restrict pc32, const char *restrict str, size_t len, + mbstate_t *restrict ps) +{ + if (ps == NULL) { + ps = &mbrtoc32_state; + } + + if (str == NULL) { + pc32 = NULL; + str = ""; + len = 1; + } + + return (mbrtowc_l((wchar_t *)pc32, str, len, ps, + uselocale((locale_t)0))); +} diff --git a/usr/src/lib/libc/port/locale/mbsinit.c b/usr/src/lib/libc/port/locale/mbsinit.c index ae956d0f15..e6227ee62e 100644 --- a/usr/src/lib/libc/port/locale/mbsinit.c +++ b/usr/src/lib/libc/port/locale/mbsinit.c @@ -17,10 +17,28 @@ #include <locale.h> #include "localeimpl.h" #include "lctype.h" +#include "mblocal.h" int mbsinit_l(const mbstate_t *s, locale_t loc) { + + /* + * To implement support for the C11 char16_t conversion functions + * (mbrtoc16() and c16rtomb()) we opted to leverage all of the existing + * conversion infrastructure, including the per-locale conversion + * structures. The char16_t conversion functions tack an extra member in + * the mbstate_t that occurs after all others have placed their data. + * Therefore, before we go to the per-locale backend we need to see if + * there is any outstanding state in the char16_t specific state. + */ + if (s != NULL) { + const _CHAR16State *c16s = (const _CHAR16State *)s; + if (c16s->c16_surrogate != 0) { + return (0); + } + } + return (loc->ctype->lc_mbsinit(s)); } diff --git a/usr/src/lib/libc/port/locale/mskanji.c b/usr/src/lib/libc/port/locale/mskanji.c index 69955e5afa..a0a1f193ce 100644 --- a/usr/src/lib/libc/port/locale/mskanji.c +++ b/usr/src/lib/libc/port/locale/mskanji.c @@ -57,10 +57,6 @@ static size_t _MSKanji_wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD); -typedef struct { - wchar_t ch; -} _MSKanjiState; - void _MSKanji_init(struct lc_ctype *lct) { diff --git a/usr/src/lib/libc/port/locale/unicode.h b/usr/src/lib/libc/port/locale/unicode.h new file mode 100644 index 0000000000..558ef2be13 --- /dev/null +++ b/usr/src/lib/libc/port/locale/unicode.h @@ -0,0 +1,68 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Robert Mustacchi + */ + +#ifndef _UNICODE_H +#define _UNICODE_H + +/* + * Common definitions for dealing with Unicode. + * + * UTF-16 encodes data as a series of two byte values. However, there are more + * than 16-bit of code points. Code points inside of the first 16-bits are + * referred to as existing in the 'basic multilingual plane' (BMP). Those + * outside of it are in the 'supplementary plane'. When such a code point is + * encountered, it is encoded as a series of two uint16_t values. + * + * A value which is up to 20 bits (the current limit of the unicode code point + * space) is encoded by splitting it into two 10-bit values. The upper 10 bits + * are ORed with 0xd800 and the lower 10 bits are ORed with 0xdc00. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Range of Unicode code points reserved for surrogate characters. + */ +#define UNICODE_SUR_MIN 0xd800 +#define UNICODE_SUR_MAX 0xdfff + +/* + * Range of Unicode code points in supplementary planes. + */ +#define UNICODE_SUP_START 0x10000 +#define UNICODE_SUP_MAX 0x10ffff + +/* + * Starting constants for surrogate pairs. + */ +#define UNICODE_SUR_UPPER 0xd800 +#define UNICODE_SUR_LOWER 0xdc00 + +/* + * Macros to extract the value from a surrogate pair and to take a code point + * and transform it into the surrogate version. + */ +#define UNICODE_SUR_UVALUE(x) (((x) & 0x3ff) << 10) +#define UNICODE_SUR_LVALUE(x) ((x) & 0x3ff) +#define UNICODE_SUR_UMASK(x) (((x) >> 10) & 0x3ff) +#define UNICODE_SUR_LMASK(x) ((x) & 0x3ff) + +#ifdef __cplusplus +} +#endif + +#endif /* _UNICODE_H */ diff --git a/usr/src/lib/libc/port/locale/utf8.c b/usr/src/lib/libc/port/locale/utf8.c index a6e037d94e..133bd3bf01 100644 --- a/usr/src/lib/libc/port/locale/utf8.c +++ b/usr/src/lib/libc/port/locale/utf8.c @@ -48,12 +48,6 @@ static size_t _UTF8_wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD); -typedef struct { - wchar_t ch; - int want; - wchar_t lbound; -} _UTF8State; - void _UTF8_init(struct lc_ctype *lct) { diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 4e24603312..8cb88fb884 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -78,6 +78,14 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.33 { + protected: + c16rtomb; + c32rtomb; + mbrtoc16; + mbrtoc32; +} ILLUMOS_0.32; + SYMBOL_VERSION ILLUMOS_0.32 { protected: fmemopen; diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index 3fb4e21fe4..7d5155b373 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -823,6 +823,8 @@ PORTI18N_COND= \ PORTLOCALE= \ big5.o \ btowc.o \ + c16rtomb.o \ + c32rtomb.o \ collate.o \ collcmp.o \ euc.o \ @@ -848,6 +850,8 @@ PORTLOCALE= \ mbftowc.o \ mblen.o \ mbrlen.o \ + mbrtoc16.o \ + mbrtoc32.o \ mbrtowc.o \ mbsinit.o \ mbsnrtowcs.o \ diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index afe2c70fa7..782f72d8e1 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -766,6 +766,8 @@ PORTI18N_COND= \ PORTLOCALE= \ big5.o \ btowc.o \ + c16rtomb.o \ + c32rtomb.o \ collate.o \ collcmp.o \ euc.o \ @@ -791,6 +793,8 @@ PORTLOCALE= \ mbftowc.o \ mblen.o \ mbrlen.o \ + mbrtoc16.o \ + mbrtoc32.o \ mbrtowc.o \ mbsinit.o \ mbsnrtowcs.o \ |