diff options
Diffstat (limited to 'usr/src')
35 files changed, 2199 insertions, 515 deletions
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile index e9beffdf71..bc9c57a6a6 100644 --- a/usr/src/head/Makefile +++ b/usr/src/head/Makefile @@ -198,6 +198,7 @@ HDRS= $($(MACH)_HDRS) \ time.h \ tiuser.h \ tzfile.h \ + uchar.h \ ucontext.h \ ucred.h \ ulimit.h \ @@ -227,7 +228,7 @@ ISOHDRS = \ locale_iso.h \ math_c99.h \ math_iso.h \ - setjmp_iso.h \ + setjmp_iso.h \ signal_iso.h \ stdarg_c99.h \ stdarg_iso.h \ @@ -243,7 +244,7 @@ ISOHDRS = \ wchar_iso.h \ wctype_iso.h -ARPAHDRS = \ +ARPAHDRS = \ ftp.h \ inet.h \ nameser.h \ @@ -410,7 +411,7 @@ $(ROOT)/usr/include/%: % .PARALLEL: $(ROOTHDRS) $(CHECKHDRS) -install_h: $(ROOTDIRS) .WAIT $(ROOTHDRS) $(SYMHDRASSERT) $(SYMHDRERRNO) \ +install_h: $(ROOTDIRS) .WAIT $(ROOTHDRS) $(SYMHDRASSERT) $(SYMHDRERRNO) \ $(SYMHDRFLOAT) $(SYMHDRISO646) check: $(CHECKHDRS) diff --git a/usr/src/head/uchar.h b/usr/src/head/uchar.h new file mode 100644 index 0000000000..83d998b4a1 --- /dev/null +++ b/usr/src/head/uchar.h @@ -0,0 +1,74 @@ +/* + * 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 _UCHAR_H +#define _UCHAR_H + +/* + * C11 Unicode utilities support. + * + * Note, we do not define either __STDC_UTF_16__ or __STDC_UTF_32__. While the + * functions that are implemented work in that fashion, the ability to represent + * any UTF-16 or UTF-32 code point depends on the current locale. Though in + * practice they function that way. + */ + +#include <sys/isa_defs.h> +#include <sys/feature_tests.h> +#include <wchar_impl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_SIZE_T) || __cplusplus >= 199711L +#define _SIZE_T +#if defined(_LP64) || defined(_I32LPx) +typedef unsigned long size_t; /* size of something in bytes */ +#else +typedef unsigned int size_t; /* (historical version) */ +#endif +#endif /* _SIZE_T */ + +#if !defined(_MBSTATE_T) || __cplusplus >= 199711L +#define _MBSTATE_T +typedef __mbstate_t mbstate_t; +#endif /* _MBSTATE_T */ + +/* + * These types must match the uint_least16_t and uint_least32_t. They are + * defined in terms of the same type so as to minimize the needed includes. + * C++11 also defines these types and they are considered built in, so we should + * not define them in that context. + */ +#if __cplusplus < 2011103L +typedef unsigned short char16_t; +typedef unsigned int char32_t; +#endif + +extern size_t mbrtoc16(char16_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, + size_t, mbstate_t *_RESTRICT_KYWD); +extern size_t mbrtoc32(char32_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, + size_t, mbstate_t *_RESTRICT_KYWD); +extern size_t c16rtomb(char *_RESTRICT_KYWD, char16_t, + mbstate_t *_RESTRICT_KYWD); +extern size_t c32rtomb(char *_RESTRICT_KYWD, char32_t, + mbstate_t *_RESTRICT_KYWD); + +#ifdef __cplusplus +} +#endif + +#endif /* _UCHAR_H */ 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 \ diff --git a/usr/src/man/man3c/Makefile b/usr/src/man/man3c/Makefile index 958b23075a..1728df06e3 100644 --- a/usr/src/man/man3c/Makefile +++ b/usr/src/man/man3c/Makefile @@ -62,6 +62,7 @@ MANFILES= __fbufsize.3c \ bstring.3c \ btowc.3c \ byteorder.3c \ + c16rtomb.3c \ call_once.3c \ catgets.3c \ catopen.3c \ @@ -238,7 +239,7 @@ MANFILES= __fbufsize.3c \ malloc.3c \ mblen.3c \ mbrlen.3c \ - mbrtowc.3c \ + mbrtoc16.3c \ mbsinit.3c \ mbsrtowcs.3c \ mbstowcs.3c \ @@ -540,7 +541,6 @@ MANFILES= __fbufsize.3c \ waitpid.3c \ walkcontext.3c \ wcpcpy.3c \ - wcrtomb.3c \ wcscasecmp.3c \ wcscoll.3c \ wcsdup.3c \ @@ -726,6 +726,7 @@ MANLINKS= FD_CLR.3c \ bindtextdomain.3c \ btowc_l.3c \ bzero.3c \ + c32rtomb.3c \ calloc.3c \ canonicalize_file_name.3c \ catclose.3c \ @@ -1003,6 +1004,8 @@ MANLINKS= FD_CLR.3c \ major.3c \ mblen_l.3c \ mbrlen_l.3c \ + mbrtoc32.3c \ + mbrtowc.3c \ mbrtowc_l.3c \ mbsinit_l.3c \ mbsnrtowcs.3c \ @@ -1382,6 +1385,7 @@ MANLINKS= FD_CLR.3c \ watol.3c \ watoll.3c \ wcpncpy.3c \ + wcrtomb.3c \ wcrtomb_l.3c \ wcscasecmp_l.3c \ wcscat.3c \ @@ -1596,6 +1600,10 @@ ntohl.3c := LINKSRC = byteorder.3c ntohll.3c := LINKSRC = byteorder.3c ntohs.3c := LINKSRC = byteorder.3c +c32rtomb.3c := LINKSRC = c16rtomb.3c +wcrtomb.3c := LINKSRC = c16rtomb.3c +wcrtomb_l.3c := LINKSRC = c16rtomb.3c + canonicalize_file_name.3c := LINKSRC = realpath.3c catclose.3c := LINKSRC = catopen.3c @@ -2009,10 +2017,12 @@ mblen_l.3c := LINKSRC = mblen.3c mbrlen_l.3c := LINKSRC = mbrlen.3c -mbrtowc_l.3c := LINKSRC = mbrtowc.3c - mbsinit_l.3c := LINKSRC = mbsinit.3c +mbrtoc32.3c := LINKSRC = mbrtoc16.3c +mbrtowc.3c := LINKSRC = mbrtoc16.3c +mbrtowc_l.3c := LINKSRC = mbrtoc16.3c + mbsnrtowcs.3c := LINKSRC = mbsrtowcs.3c mbsnrtowcs_l.3c := LINKSRC = mbsrtowcs.3c mbsrtowcs_l.3c := LINKSRC = mbsrtowcs.3c @@ -2506,8 +2516,6 @@ printstack.3c := LINKSRC = walkcontext.3c wcpncpy.3c := LINKSRC = wcpcpy.3c -wcrtomb_l.3c := LINKSRC = wcrtomb.3c - wcscasecmp_l.3c := LINKSRC = wcscasecmp.3c wcsncasecmp.3c := LINKSRC = wcscasecmp.3c wcsncasecmp_l.3c := LINKSRC = wcscasecmp.3c diff --git a/usr/src/man/man3c/c16rtomb.3c b/usr/src/man/man3c/c16rtomb.3c new file mode 100644 index 0000000000..33c6189dd3 --- /dev/null +++ b/usr/src/man/man3c/c16rtomb.3c @@ -0,0 +1,285 @@ +.\" +.\" 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 +.\" +.Dd April 23, 2020 +.Dt C16RTOMB 3C +.Os +.Sh NAME +.Nm c16rtomb , +.Nm c32rtomb , +.Nm wcrtomb , +.Nm wcrtomb_l +.Nd convert wide-characters to character sequences +.Sh SYNOPSIS +.In uchar.h +.Ft size_t +.Fo c16rtomb +.Fa "char *restrict str" +.Fa "char16_t c16" +.Fa "mbstate_t *restrict ps" +.Fc +.Ft size_t +.Fo c32rtomb +.Fa "char *restrict str" +.Fa "char32_t c32" +.Fa "mbstate_t *restrict ps" +.Fc +.In stdio.h +.Ft size_t +.Fo wcrtomb +.Fa "char *restrict str" +.Fa "wchar_t wc" +.Fa "mbstate_t *restrict ps" +.Fc +.In stdio.h +.In xlocale.h +.Ft size_t +.Fo wcrtomb_l +.Fa "char *restrict str" +.Fa "wchar_t wc" +.Fa "mbstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.Sh DESCRIPTION +The +.Fn c16rtomb , +.Fn c32rtomb , +.Fn wcrtomb , +and +.Fn wcrtomb_l +functions convert wide-character sequences into a series of multi-byte +characters. +The functions work in the following formats: +.Bl -tag -width wcrtomb_l +.It Fn c16rtomb +A UTF-16 code sequence, where every code point is represented by one or +two +.Vt char16_t . +The UTF-16 encoding will encode certain Unicode code points as a pair of +two 16-bit code sequences, commonly referred to as a surrogate pair. +.It Fn c32rtomb +A UTF-32 code sequence, where every code point is represented by a +single +.Vt char32_t . +It is illegal to pass reserved Unicode code points. +.It Fn wcrtomb , Fn wcrtomb_l +Wide characters, being a 32-bit value where every code point is +represented by a single +.Vt wchar_t . +While the +.Vt wchar_t +and +.Vt char32_t +are different types, in this implementation, they are similar encodings. +.El +.Pp +The functions all work by looking at the passed in wide-character +.Po +.Fa c16 , +.Fa c32 , +.Fa wc +.Pc +and appending it to the current conversion state, +.Fa ps . +Once a valid code point, based on the current locale, is found, then it +will be converted into a series of characters that are stored in +.Fa str . +Up to +.Dv MB_CUR_MAX +bytes will be stored in +.Fa str . +It is the caller's responsibility to ensure that there is sufficient +space in +.Fa str . +.Pp +The functions are all influenced by the +.Dv LC_CTYPE +category of the current locale for determining what is considered a +valid character. +For example, in the +.Sy C +locale, +only ASCII characters are recognized, while in a +.Sy UTF-8 +based locale like +.Sy en_us.UTF-8 , +all valid Unicode code points are recognized and will be converted into +the corresponding multi-byte sequence. +The +.Fn wcrtomb_l +function uses the locale passed in +.Fa loc +rather than the locale of the current thread. +.Pp +The +.Fa ps +argument represents a multi-byte conversion state which can be used +across multiple calls to a given function +.Pq but not mixed between functions . +These allow for characters to be consumed from subsequent buffers, e.g. +different values of +.Fa str . +The functions may be called from multiple threads as long as they use +unique values for +.Fa ps . +If +.Fa ps +is +.Dv NULL , +then a function-specific buffer will be used for the conversion state; +however, this is stored between all threads and its use is not +recommended. +.Pp +The functions all have a special behavior when +.Dv NULL +is passed for +.Fa str . +They instead will treat it as though a the NULL wide-character was +passed in +.Fa c16 , +.Fa c32 , +or +.Fa wc +and an internal buffer +.Pq buf +will be used to write out the results of the +converstion. +In other words, the functions would be called as: +.Bd -literal -offset indent +c16rtomb(buf, L'\\0', ps) +c32rtomb(buf, L'\\0', ps) +wcrtomb(buf, L'\\0', ps) +wcrtomb_l(buf, L'\\0', ps, loc) +.Ed +.Ss Locale Details +Not all locales in the system are Unicode based locales. +For example, ISO 8859 family locales have code points with values that +do not match their counterparts in Unicode. +When using these functions with non-Unicode based locales, the code +points returned will be those determined by the locale. +They will not be converted from the corresponding Unicode code point. +For example, if using the Euro sign in ISO 8859-15, these functions +will not encode the Unicode value 0x20ac into the ISO 8859-15 value +0xa4. +.Pp +Regardless of the locale, the characters returned will be encoded as +though the code point were the corresponding value in Unicode. +This means that when using UTF-16, if the corresponding code point were +in the range for surorgate pairs, then the +.Fn c16rtomb +function will expect to receive that code point in that fashion. +.Pp +This behavior of the +.Fn c16rtomb +and +.Fn c32rtomb +functions should not be relied upon, is not portable, and subject to +change for non-Unicode locales. +.Sh RETURN VALUES +Upon successful completion, the +.Fn c16rtomb , +.Fn c32rtomb , +.Fn wcrtomb , +and +.Fn wcrtomb_l +functions return the number of bytes stored in +.Fa str . +Otherwise, +.Sy (size_t)-1 +is returned to indicate an encoding error and +.Va errno +is set. +.Sh EXAMPLES +.Sy Example 1 +Converting a UTF-32 character into a multi-byte character sequence. +.Bd -literal +#include <locale.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <stdio.h> +#include <uchar.h> + +int +main(void) +{ + mbstate_t mbs; + size_t ret; + char buf[MB_CUR_MAX]; + char32_t val = 0x5149; + const char *uchar_exp = "\exe5\ex85\ex89"; + + (void) memset(&mbs, 0, sizeof (mbs)); + (void) setlocale(LC_CTYPE, "en_US.UTF-8"); + ret = c32rtomb(buf, val, &mbs); + if (ret != strlen(uchar_exp)) { + errx(EXIT_FAILURE, "failed to convert string, got %zd", + ret); + } + + if (strncmp(buf, uchar_exp, ret) != 0) { + errx(EXIT_FAILURE, "converted char32_t does not match " + "expected value"); + } + + return (0); +} +.Ed +.Sh ERRORS +The +.Fn c16rtomb , +.Fn c32rtomb , +.Fn wcrtomb , +and +.Fn wcrtomb_l +functions will fail if: +.Bl -tag -width Er +.It Er EINVAL +The conversion state in +.Fa ps +is invalid. +.It Er EILSEQ +An invalid character sequence has been detected. +.El +.Sh MT-LEVEL +The +.Fn c16rtomb , +.Fn c32rtomb , +.Fn wcrtomb , +and +.Fn wcrtomb_l +functions are +.Sy MT-Safe +as long as different +.Vt mbstate_t +structures are passed in +.Fa ps . +If +.Fa ps +is +.Dv NULL +or different threads use the same value for +.Fa ps , +then the functions are +.Sy Unsafe . +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr mbrtoc16 3C , +.Xr mbrtoc32 3C , +.Xr mbrtowc 3C , +.Xr newlocale 3C , +.Xr setlocale 3C , +.Xr uselocale 3C , +.Xr uchar.h 3HEAD , +.Xr environ 5 diff --git a/usr/src/man/man3c/mbrtoc16.3c b/usr/src/man/man3c/mbrtoc16.3c new file mode 100644 index 0000000000..d1b3ab478b --- /dev/null +++ b/usr/src/man/man3c/mbrtoc16.3c @@ -0,0 +1,397 @@ +.\" +.\" 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 +.\" +.Dd April 23, 2020 +.Dt MBRTOC16 3C +.Os +.Sh NAME +.Nm mbrtoc16 , +.Nm mbrtoc32 , +.Nm mbrtowc , +.Nm mbrtowc_l +.Nd convert characters to wide characters +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbrtowc +.Fa "wchar_t *restrict pwc" +.Fa "const char *restrict str" +.Fa "size_t len" +.Fa "mstate_t *restrict ps" +.Fc +.In wchar.h +.In xlocale.h +.Ft size_t +.Fo mbrtowc +.Fa "wchar_t *restrict pwc" +.Fa "const char *restrict str" +.Fa "size_t len" +.Fa "mstate_t *restrict ps" +.Fa "locale_t loc" +.Fc +.In uchar.h +.Ft size_t +.Fo mbrtoc16 +.Fa "char16_t *restrict p16c" +.Fa "const char *restrict str" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fc +.Ft size_t +.Fo mbrtoc32 +.Fa "char32_t *restrict p32c" +.Fa "const char *restrict str" +.Fa "size_t len" +.Fa "mbstate_t *restrict ps" +.Fc +.Sh DESCRIPTION +The +.Fn mbrtoc16 , +.Fn mbrtoc32 , +.Fn mbrtowc , +and +.Fn mbrtowc_l +functions convert character sequences, which may contain multi-byte +characters, into different character formats. +The functions work in the following formats: +.Bl -tag -width mbrtowc_l +.It Fn mbrtoc16 +A UTF-16 code sequence, where every code point is represented by one or +two +.Vt char16_t . +The UTF-16 encoding will encode certain Unicode code points as a pair of +two 16-bit code sequences, commonly referred to as a surrogate pair. +.It Fn mbrtoc32 +A UTF-32 code sequence, where every code point is represented by a +single +.Vt char32_t . +.It Fn mbrtowc , Fn mbrtowc_l +Wide characters, being a 32-bit value where every code point is +represented by a single +.Vt wchar_t . +While the +.Vt wchar_t +and +.Vt char32_t +are different types, in this implementation, they are similar encodings. +.El +.Pp +The functions consume up to +.Fa len +characters from the string +.Fa str +and accumulate them in +.Fa ps +until a valid character is found, which is influenced by +the +.Dv LC_CTYPE +category of the current locale. +For example, in the +.Sy C +locale, only ASCII characters are recognized, while in a +.Sy UTF-8 +based locale like +.Sy en_US.UTF-8 , +UTF-8 multi-byte character sequences that represent Unicode code points +are recognized. +The +.Fn mbrtowc_l +function uses the locale passed in +.Fa loc +rather than the locale of the current thread. +.Pp +When a valid character sequence has been found, it is converted to +either a 16-bit character sequence for +.Fn mbrtoc16 +or a 32-bit character sequence for +.Fn mbrtoc32 +and will be stored in +.Fa p16c +and +.Fa p32c +respectively. +.Pp +The +.Fa ps +argument represents a multi-byte conversion state which can be used +across multiple calls to a given function +.Pq but not mixed between functions . +These allow for characters to be consumed from subsequent buffers, e.g. +different values of +.Fa str . +The functions may be called from multiple threads as long as they use +unique values for +.Fa ps . +If +.Fa ps +is +.Dv NULL , +then a function-specific buffer will be used for the conversion state; +however, this is stored between all threads and its use is not +recommended. +.Pp +When using these functions, more than one character may be output for a +given set of consumed input characters. +An example of this is when a given code point is represented as a set of +surrogate pairs in UTF-16, which require two 16-bit characters to +represent a code point. +When this occurs, the functions return the special return value +.Sy -3 . +.Pp +The functions all have a special behavior when +.Dv NULL +is passed for +.Fa str . +They instead will treat it as though +.Fa pwc , +.Fa p16c , +or +.Fa p32c +were +.Dv NULL , +.Fa str +had been passed as the empty string, "" and the length, +.Fa len , +would appear as the value 1. +In other words, the functions would be called as: +.Bd -literal -offset indent +mbrtowc(NULL, "", 1, ps) +mbrtowc_l(NULL, "", 1, ps) +mbrtoc16(NULL, "", 1, ps) +mbrtoc32(NULL, "", 1, ps) +.Ed +.Ss Locale Details +Not all locales in the system are Unicode based locales. +For example, ISO 8859 family locales have code points with values that +do not match their counterparts in Unicode. +When using these functions with non-Unicode based locales, the code +points returned will be those determined by the locale. +They will not be converted to the corresponding Unicode code point. +For example, if using the Euro sign in ISO 8859-15, these functions +might return the code point 0xa4 and not the Unicode value 0x20ac. +.Pp +Regardless of the locale, the characters returned will be encoded as +though the code point were the corresponding value in Unicode. +This means that if a locale returns a value that would be a surrogate +pair in the UTF-16 encoding, it will still be encoded as a UTF-16 +character. +.Pp +This behavior of the +.Fn mbrtoc16 +and +.Fn mbrtoc32 +functions should not be relied upon, is not portable, and subject to +change for non-Unicode locales. +.Sh RETURN VALUES +The +.Fn mbrtoc16 , +.Fn mbrtoc32 , +.Fn mbrtowc , +and +.Fn mbrtowc_l +functions return the following values: +.Bl -tag -width (size_t)-3 +.It Sy 0 +.Fa len +or fewer bytes of +.Fa str +were consumed and the null wide character was written into the wide +character buffer +.Po +.Fa pwc , +.Fa p16c , +.Fa p32c +.Pc . +.It Sy between 1 and len +The specified number of bytes were consumed and a single character was +written into the wide character buffer +.Po +.Fa pwc , +.Fa p16c , +.Fa p32c +.Pc . +.It Sy (size_t)-1 +An encoding error has occurred. +The next +.Fa len +bytes of +.Fa str +do not contribute to a valid character. +.Va errno +has been set to +.Er EILSEQ . +No data was written into the wide character buffer +.Po +.Fa pwc , +.Fa p16c , +.Fa p32c +.Pc . +.It Sy (size_t)-2 +.Fa len +bytes of +.Fa str +were consumed, but a complete multi-byte character sequence has not been +found and no data was written into the wide character buffer +.Po +.Fa pwc , +.Fa p16c , +.Fa p32c +.Pc . +.It Sy (size_t)-3 +A character has been written into the wide character buffer +.Po +.Fa pwc , +.Fa p16c , +.Fa p32c +.Pc . +This character was from a previous call (such as another part of a +UTF-16 surrogate pair) and no input was consumed. +This is limited to the +.Fn mbrtoc16 +and +.Fn mbrtoc32 +functions. +.El +.Sh EXAMPLES +.Sy Example 1 +Using the +.Fn mbrtoc32 +function to convert a multibyte string. +.Bd -literal +#include <locale.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <stdio.h> +#include <uchar.h> + +int +main(void) +{ + mbstate_t mbs; + char32_t out; + size_t ret; + const char *uchar_str = "\exe5\ex85\ex89"; + + (void) memset(&mbs, 0, sizeof (mbs)); + (void) setlocale(LC_CTYPE, "en_US.UTF-8"); + ret = mbrtoc32(&out, uchar_str, strlen(uchar_str), &mbs); + if (ret != strlen(uchar_str)) { + errx(EXIT_FAILURE, "failed to convert string, got %zd", + ret); + } + + (void) printf("Converted %zu bytes into UTF-32 character " + "0x%x\n", ret, out); + return (0); +} +.Ed +.Pp +When compiled and run, this produces: +.Bd -literal -offset indent +$ ./a.out +Converted 3 bytes into UTF-32 character 0x5149 +.Ed +.Pp +.Sy Example 2 +Handling surrogate pairs from the +.Fn mbrtoc16 +function. +.Bd -literal +#include <locale.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <stdio.h> +#include <uchar.h> + +int +main(void) +{ + mbstate_t mbs; + char16_t first, second; + size_t ret; + const char *uchar_str = "\exf0\ex9f\ex92\exa9"; + + (void) memset(&mbs, '\0', sizeof (mbs)); + (void) setlocale(LC_CTYPE, "en_US.UTF-8"); + ret = mbrtoc16(&first, uchar_str, strlen(uchar_str), &mbs); + if (ret != strlen(uchar_str)) { + errx(EXIT_FAILURE, "failed to convert string, got %zd", + ret); + } + + ret = mbrtoc16(&second, "", 0, &mbs); + if (ret != (size_t)-3) { + errx(EXIT_FAILURE, "didn't get second surrogate pair, " + "got %zd", ret); + } + + (void) printf("UTF-16 surrogates: 0x%x 0x%x\n", first, second); + return (0); +} +.Ed +.Pp +When compiled and run, this produces: +.Bd -literal -offset indent +$ ./a.out +UTF-16 surrogates: 0xd83d 0xdca9 +.Ed +.Sh ERRORS +The +.Fn mbrtoc16 , +.Fn mbrtoc32 , +.Fn mbrtowc , +and +.Fn mbrtowc_l +functions will fail if: +.Bl -tag -width Er +.It Er EINVAL +The conversion state in +.Fa ps +is invalid. +.It Er EILSEQ +An invalid character sequence has been detected. +.El +.Sh MT-LEVEL +The +.Fn mbrtoc16 , +.Fn mbrtoc32 , +.Fn mbrtowc , +and +.Fn mbrtowc_l +functions are +.Sy MT-Safe +as long as different +.Vt mbstate_t +structures are passed in +.Fa ps . +If +.Fa ps +is +.Dv NULL +or different threads use the same value for +.Fa ps , +then the functions are +.Sy Unsafe . +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr c16rtomb 3C , +.Xr c32rtomb 3C , +.Xr newlocale 3C , +.Xr setlocale 3C , +.Xr uselocale 3C , +.Xr wcrtomb 3C , +.Xr uchar.h 3HEAD , +.Xr environ 5 diff --git a/usr/src/man/man3c/mbrtowc.3c b/usr/src/man/man3c/mbrtowc.3c deleted file mode 100644 index 70fe73d25e..0000000000 --- a/usr/src/man/man3c/mbrtowc.3c +++ /dev/null @@ -1,231 +0,0 @@ -.\" -.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for -.\" permission to reproduce portions of its copyrighted documentation. -.\" Original documentation from The Open Group can be obtained online at -.\" http://www.opengroup.org/bookstore/. -.\" -.\" The Institute of Electrical and Electronics Engineers and The Open -.\" Group, have given us permission to reprint portions of their -.\" documentation. -.\" -.\" In the following statement, the phrase ``this text'' refers to portions -.\" of the system documentation. -.\" -.\" Portions of this text are reprinted and reproduced in electronic form -.\" in the SunOS Reference Manual, from IEEE Std 1003.1, 2004 Edition, -.\" Standard for Information Technology -- Portable Operating System -.\" Interface (POSIX), The Open Group Base Specifications Issue 6, -.\" Copyright (C) 2001-2004 by the Institute of Electrical and Electronics -.\" Engineers, Inc and The Open Group. In the event of any discrepancy -.\" between these versions and the original IEEE and The Open Group -.\" Standard, the original IEEE and The Open Group Standard is the referee -.\" document. The original Standard can be obtained online at -.\" http://www.opengroup.org/unix/online.html. -.\" -.\" This notice shall appear on any product containing this material. -.\" -.\" The contents of this file are subject to the terms of the -.\" Common Development and Distribution License (the "License"). -.\" You may not use this file except in compliance with the License. -.\" -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -.\" or http://www.opensolaris.org/os/licensing. -.\" See the License for the specific language governing permissions -.\" and limitations under the License. -.\" -.\" When distributing Covered Code, include this CDDL HEADER in each -.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. -.\" If applicable, add the following below this CDDL HEADER, with the -.\" fields enclosed by brackets "[]" replaced with your own identifying -.\" information: Portions Copyright [yyyy] [name of copyright owner] -.\" -.\" -.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. -.\" Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved. -.\" Copyright 2014 Garrett D'Amore <garrett@damore.org> -.\" -.TH MBRTOWC 3C "Jun 23, 2014" -.SH NAME -mbrtowc, mbrtowc_l \- convert a character to a wide-character code (restartable) -.SH SYNOPSIS -.LP -.nf -#include <wchar.h> - -\fBsize_t\fR \fBmbrtowc\fR(\fBwchar_t *restrict\fR \fIpwc\fR, \fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR, - \fBmbstate_t *restrict\fR \fIps\fR); -.fi -.LP -.nf -#include <wchar.h> -#include <xlocale.h> - -\fBsize_t\fR \fBmbrtowc_l\fR(\fBwchar_t *restrict\fR \fIpwc\fR, \fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR, - \fBmbstate_t *restrict\fR \fIps\fR, \fBlocale_t\fR \fIloc\fR); -.fi -.SH DESCRIPTION -.LP -If -.I s -is a null pointer, the -.B mbrtowc() -function is equivalent to the call: -.sp -.in +2 -.nf -\fBmbrtowc\fR(NULL, "", 1, \fIps\fR) -.fi -.in -2 -.LP -Likewise, if -.I s -is a null pointer, the -.B mbrtowc_l() -function is equivalent to the call: -.sp -.in +2 -.nf -\fBmbrtowc_l\fR(NULL, "", 1, \fIps\fR, \fIloc\fR); -.fi -.in -2 -.LP -In these cases, the values of the arguments -.I pwc -and -.I n -are ignored. -.LP -If -.I s -is not a null pointer, these functions inspect at most -.I n -bytes beginning at the byte pointed to by -.I s -to determine the number of bytes needed to complete the next character -(including any shift sequences). If the functions determine that the next -character is completed, -they determine the value of the corresponding wide-character and then, if -.I pwc -is not a null pointer, stores that value in the object pointed to by -.IR pwc . -If the corresponding wide-character is the null wide-character, the -resulting state described is the initial conversion state. -.LP -If -.I ps -is a null pointer, these functions use their own -internal -.B mbstate_t -object, which is initialized at program startup to the -initial conversion state. Otherwise, the -.B mbstate_t -object pointed to by -.I ps -is used to completely describe the current conversion state of the -associated character sequence. The system will behave as if no function defined -in the Reference Manual calls -.B mbrtowc() -or -.BR Bmbrtowc_l() . -.LP -The behavior of -.B mbrtowc() -is affected by the -.B LC_CTYPE -category of the current locale. The -.B mbrtowc_l() -function is affected by the -.B LC_CTYPE -category of the specified -.I loc -locale object. See -.B environ (5). -.SH RETURN VALUES -.LP -The -.B mbrtowc() -and -.B mbrtowc_l() -functions return the first of the following that applies: -.IP \fB0\fR -If the next -.I n -or fewer bytes complete the character that corresponds to -the null wide-character (which is the value stored). -.IP \fBpositive\fR -If the next -.I n -or fewer bytes complete a valid character (which is the -value stored); the value returned is the number of bytes that complete the -character. -.IP \fB(size_t)\(mi2\fR -If the next -.I n -bytes contribute to an incomplete but potentially valid -character, and all -.I n -bytes have been processed (no value is stored). -When -.I n -has at least the value of the -.B MB_CUR_MAX -macro, this case can only occur if -.I s -points at a sequence of redundant shift sequences -(for implementations with state-dependent encodings). -.IP \fB(size_t)\(mi1\fR -If an encoding error occurs, in which case the next \fIn\fR or fewer bytes do -not contribute to a complete and valid character (no value is stored). In -this case, -.B EILSEQ -is stored in -.B errno -and the conversion state is undefined. -.SH ERRORS -.LP -The -.B mbrtowc() -and -.B mbrtowc_l() -functions may fail if: -.IP \fBEINVAL\fR -The -.I ps -argument points to an object that contains an invalid conversion -state. -.IP \fBEILSEQ\fR -Invalid character sequence is detected. -.SH ATTRIBUTES -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability See below. -_ -MT-Level See below. -.TE - -.LP -The -.B mbrtowc() -function is Standard. The -.B mbrtowc_l() -function is Uncommitted. -.LP -If -.I ps -is a null pointer, these functions are Unsafe for use in -multithreaded applications. Otherwise they are MT-Safe. -.SH SEE ALSO -.LP -.BR mbsinit (3C), -.BR newlocale (3C), -.BR setlocale (3C), -.BR uselocale (3C), -.BR attributes (5), -.BR environ (5), -.BR standards (5) diff --git a/usr/src/man/man3c/wcrtomb.3c b/usr/src/man/man3c/wcrtomb.3c deleted file mode 100644 index 9a3478cb07..0000000000 --- a/usr/src/man/man3c/wcrtomb.3c +++ /dev/null @@ -1,146 +0,0 @@ -.\" -.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for -.\" permission to reproduce portions of its copyrighted documentation. -.\" Original documentation from The Open Group can be obtained online at -.\" http://www.opengroup.org/bookstore/. -.\" -.\" The Institute of Electrical and Electronics Engineers and The Open -.\" Group, have given us permission to reprint portions of their -.\" documentation. -.\" -.\" In the following statement, the phrase ``this text'' refers to portions -.\" of the system documentation. -.\" -.\" Portions of this text are reprinted and reproduced in electronic form -.\" in the SunOS Reference Manual, from IEEE Std 1003.1, 2004 Edition, -.\" Standard for Information Technology -- Portable Operating System -.\" Interface (POSIX), The Open Group Base Specifications Issue 6, -.\" Copyright (C) 2001-2004 by the Institute of Electrical and Electronics -.\" Engineers, Inc and The Open Group. In the event of any discrepancy -.\" between these versions and the original IEEE and The Open Group -.\" Standard, the original IEEE and The Open Group Standard is the referee -.\" document. The original Standard can be obtained online at -.\" http://www.opengroup.org/unix/online.html. -.\" -.\" This notice shall appear on any product containing this material. -.\" -.\" The contents of this file are subject to the terms of the -.\" Common Development and Distribution License (the "License"). -.\" You may not use this file except in compliance with the License. -.\" -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -.\" or http://www.opensolaris.org/os/licensing. -.\" See the License for the specific language governing permissions -.\" and limitations under the License. -.\" -.\" When distributing Covered Code, include this CDDL HEADER in each -.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. -.\" If applicable, add the following below this CDDL HEADER, with the -.\" fields enclosed by brackets "[]" replaced with your own identifying -.\" information: Portions Copyright [yyyy] [name of copyright owner] -.\" -.\" -.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. -.\" Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved. -.\" Copyright 2014 Garrett D'Amore <garrett@damore.org> -.\" -.TH WCRTOMB 3C "Jun 24, 2014" -.SH NAME -wcrtomb, wcrtomb_l \- convert a wide-character code to a character (restartable) -.SH SYNOPSIS -.LP -.nf -#include <stdio.h> - -\fBsize_t\fR \fBwcrtomb\fR(\fBchar *restrict\fR \fIs\fR, \fBwchar_t\fR \fIwc\fR, \fBmbstate_t *restrict\fR \fIps\fR); -.fi -.LP -.nf -#include <stdio.h> -#include <xlocale.h> - -\fBsize_t\fR \fBwcrtomb_l\fR(\fBchar *restrict\fR \fIs\fR, \fBwchar_t\fR \fIwc\fR, \fBmbstate_t *restrict\fR \fIps\fR, - \fBlocale_t\fR \fIloc\fR); -.fi -.SH DESCRIPTION -.LP -If \fIs\fR is a null pointer, the \fBwcrtomb()\fR function is equivalent to the -call: -.IP -\fBwcrtomb\fR(\fIbuf\fR, L'\e0', \fIps\fR); -.LP -where \fIbuf\fR is an internal buffer. -.LP -If \fIs\fR is not a null pointer, the \fBwcrtomb()\fR function determines the -number of bytes needed to represent the character that corresponds to the -wide-character given by \fIwc\fR (including any shift sequences), and stores -the resulting bytes in the array whose first element is pointed to by \fIs\fR. -At most \fBMB_CUR_MAX\fR bytes are stored. If \fIwc\fR is a null -wide-character, a null byte is stored, preceded by any shift sequence needed to -restore the initial shift state. The resulting state described is the initial -conversion state. -.LP -If \fIps\fR is a null pointer, the \fBwcrtomb()\fR function uses its own -internal \fBmbstate_t\fR object, which is initialized at program startup to the -initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to -by \fIps\fR is used to completely describe the current conversion state of the -associated character sequence. The system will behave as if no function -defined in the Reference Manual calls \fBwcrtomb()\fR. -.LP -The behavior of \fBwcrtomb()\fR is affected by the \fBLC_CTYPE\fR category of the -current locale. See \fBenviron\fR(5). The function \fBwcrtomb_l()\fR behaves -identically to \fBwcrtomb()\fR, except instead of operating in the current -locale, it operates in the locale specified by \fIloc\fR. -.SH RETURN VALUES -.LP -The \fBwcrtomb()\fR function returns the number of bytes stored in the array -object (including any shift sequences). When \fIwc\fR is not a valid -wide-character, an encoding error occurs. In this case, the function stores -the value of the macros \fBEILSEQ\fR in \fBerrno\fR and returns -\fB(size_t)\(mi1\fR; the conversion state is undefined. -.SH ERRORS -.LP -The \fBwcrtomb()\fR function may fail if: -.sp -.ne 2 -.na -\fB\fBEINVAL\fR\fR -.ad -.RS 10n -The \fIps\fR argument points to an object that contains an invalid conversion -state. -.RE - -.sp -.ne 2 -.na -\fB\fBEILSEQ\fR\fR -.ad -.RS 10n -Invalid wide-character code is detected. -.RE -.SH ATTRIBUTES -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability See below. -_ -MT-Level See below. -.TE - -.LP -The \fBwcrtomb()\fR function is Standard. The -\fBwcrtomb_l()\fR function is Uncommitted. -.LP -If \fIps\fR is a null pointer, these functions should be considered Unsafe -for use in multithreaded applications. Otherwise, they are MT-Safe. -.SH SEE ALSO -.LP -\fBmbsinit\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C), -\fBuselocale\fR(3C), \fBattributes\fR(5), -\fBstandards\fR(5), \fBenviron\fR(5) diff --git a/usr/src/man/man3head/Makefile b/usr/src/man/man3head/Makefile index e212c67457..fdc94ef4ef 100644 --- a/usr/src/man/man3head/Makefile +++ b/usr/src/man/man3head/Makefile @@ -17,98 +17,99 @@ include $(SRC)/Makefile.master -MANSECT= 3head +MANSECT= 3head MANFILES= acct.h.3head \ - aio.h.3head \ - ar.h.3head \ - archives.h.3head \ - assert.h.3head \ - complex.h.3head \ - cpio.h.3head \ - dirent.h.3head \ + aio.h.3head \ + ar.h.3head \ + archives.h.3head \ + assert.h.3head \ + complex.h.3head \ + cpio.h.3head \ + dirent.h.3head \ endian.h.3head \ - errno.h.3head \ - fcntl.h.3head \ - fenv.h.3head \ - float.h.3head \ - floatingpoint.h.3head \ - fmtmsg.h.3head \ - fnmatch.h.3head \ - ftw.h.3head \ - glob.h.3head \ - grp.h.3head \ - iconv.h.3head \ - if.h.3head \ - in.h.3head \ - inet.h.3head \ - inttypes.h.3head \ - ipc.h.3head \ - iso646.h.3head \ - langinfo.h.3head \ - libgen.h.3head \ - libintl.h.3head \ - limits.h.3head \ - locale.h.3head \ - math.h.3head \ - mman.h.3head \ - monetary.h.3head \ - mqueue.h.3head \ - msg.h.3head \ - ndbm.h.3head \ - netdb.h.3head \ - nl_types.h.3head \ - poll.h.3head \ - pthread.h.3head \ - pwd.h.3head \ + errno.h.3head \ + fcntl.h.3head \ + fenv.h.3head \ + float.h.3head \ + floatingpoint.h.3head \ + fmtmsg.h.3head \ + fnmatch.h.3head \ + ftw.h.3head \ + glob.h.3head \ + grp.h.3head \ + iconv.h.3head \ + if.h.3head \ + in.h.3head \ + inet.h.3head \ + inttypes.h.3head \ + ipc.h.3head \ + iso646.h.3head \ + langinfo.h.3head \ + libgen.h.3head \ + libintl.h.3head \ + limits.h.3head \ + locale.h.3head \ + math.h.3head \ + mman.h.3head \ + monetary.h.3head \ + mqueue.h.3head \ + msg.h.3head \ + ndbm.h.3head \ + netdb.h.3head \ + nl_types.h.3head \ + poll.h.3head \ + pthread.h.3head \ + pwd.h.3head \ queue.h.3head \ - regex.h.3head \ - resource.h.3head \ - sched.h.3head \ - search.h.3head \ - select.h.3head \ - sem.h.3head \ - semaphore.h.3head \ - setjmp.h.3head \ - shm.h.3head \ - siginfo.h.3head \ - signal.h.3head \ - socket.h.3head \ - spawn.h.3head \ - stat.h.3head \ - statvfs.h.3head \ - stdbool.h.3head \ - stddef.h.3head \ - stdint.h.3head \ - stdio.h.3head \ - stdlib.h.3head \ - string.h.3head \ - strings.h.3head \ - stropts.h.3head \ - syslog.h.3head \ - tar.h.3head \ - tcp.h.3head \ - termios.h.3head \ - tgmath.h.3head \ - time.h.3head \ - timeb.h.3head \ - times.h.3head \ - types.h.3head \ - types32.h.3head \ - ucontext.h.3head \ - uio.h.3head \ - ulimit.h.3head \ - un.h.3head \ - unistd.h.3head \ - utime.h.3head \ - utmpx.h.3head \ - utsname.h.3head \ - values.h.3head \ - wait.h.3head \ - wchar.h.3head \ - wctype.h.3head \ - wordexp.h.3head \ - xlocale.h.3head + regex.h.3head \ + resource.h.3head \ + sched.h.3head \ + search.h.3head \ + select.h.3head \ + sem.h.3head \ + semaphore.h.3head \ + setjmp.h.3head \ + shm.h.3head \ + siginfo.h.3head \ + signal.h.3head \ + socket.h.3head \ + spawn.h.3head \ + stat.h.3head \ + statvfs.h.3head \ + stdbool.h.3head \ + stddef.h.3head \ + stdint.h.3head \ + stdio.h.3head \ + stdlib.h.3head \ + string.h.3head \ + strings.h.3head \ + stropts.h.3head \ + syslog.h.3head \ + tar.h.3head \ + tcp.h.3head \ + termios.h.3head \ + tgmath.h.3head \ + time.h.3head \ + timeb.h.3head \ + times.h.3head \ + types.h.3head \ + types32.h.3head \ + uchar.h.3head \ + ucontext.h.3head \ + uio.h.3head \ + ulimit.h.3head \ + un.h.3head \ + unistd.h.3head \ + utime.h.3head \ + utmpx.h.3head \ + utsname.h.3head \ + values.h.3head \ + wait.h.3head \ + wchar.h.3head \ + wctype.h.3head \ + wordexp.h.3head \ + xlocale.h.3head MANLINKS= \ LIST_CLASS_ENTRY.3head \ diff --git a/usr/src/man/man3head/uchar.h.3head b/usr/src/man/man3head/uchar.h.3head new file mode 100644 index 0000000000..cb34b7f69a --- /dev/null +++ b/usr/src/man/man3head/uchar.h.3head @@ -0,0 +1,95 @@ +.\" +.\" 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 +.\" +.Dd April 22, 2020 +.Dt UCHAR.H 3HEAD +.Os +.Sh NAME +.Nm uchar.h +.Nd unicode utilities header +.Sh SYNOPSIS +.In uchar.h +.Sh DESCRIPTION +The +.In uchar.h +header provides support for the C11 Unicode utilities. +The types and functions provide means for working with data encoded as +UTF-16 and UTF-32. +When working in non-Unicode locales, these types may not represent +Unicode code points. +.Pp +The +.In uchar.h +header defines the following types: +.Bl -tag -width Vt +.It Vt char16_t +An unsigned integer that can represent 16-bit characters, generally a +single single UTF-16 code unit. +A Unicode code point may be one or two UTF-16 code units due to +surrogate pairs. +.It Vt char32_t +An unsigned integer that can represent 32-bit characters, generally a +single UTF-32 code unit. +.It Vt size_t +An unsigned integer that represents the size of various objects. +This can hold the result of the +.Sy sizeof +operator. +See also +.Xr stddef.h 3HEAD . +.It Vt mbstate_t +An object that holds the state for converting between character +sequences and wide characters +.Po +.Vt wchar_t , +.Vt char16_t , +.Vt char32_t +.Pc . +See also, +.Xr wchar.h 3HEAD . +.El +The +.In uchar.h +header also defines the following functions which are used to convert +between +.Vt char16_t +and +.Vt char32_t +sequences and other character sequences: +.Bl -tag -width cr16rtomb +.It Xr c16rtomb 3C +Convert +.Vt char16_t +sequences to multi-byte character sequences. +.It Xr c32rtomb 3C +Convert +.Vt char32_t +sequences to multi-byte character sequences. +.It Xr mbrtoc16 3C +Convert multi-byte character sequences to +.Vt char16_t +sequences. +.It Xr mbrtoc32 3C +Convert multi-byte character sequences to +.Vt char32_t +sequences. +.El +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr c16rtomb 3C , +.Xr c32rtomb 3C , +.Xr mbrtoc16 3C , +.Xr mbrtoc32 3C , +.Xr stddef.h 3HEAD , +.Xr wchar.h 3HEAD diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf index 5098ae075a..8a5436aba7 100644 --- a/usr/src/pkg/manifests/system-header.mf +++ b/usr/src/pkg/manifests/system-header.mf @@ -1604,6 +1604,7 @@ file path=usr/include/time.h file path=usr/include/tiuser.h file path=usr/include/tsol/label.h file path=usr/include/tzfile.h +file path=usr/include/uchar.h file path=usr/include/ucontext.h file path=usr/include/ucred.h file path=usr/include/uid_stp.h @@ -1910,6 +1911,7 @@ file path=usr/share/man/man3head/timeb.h.3head file path=usr/share/man/man3head/times.h.3head file path=usr/share/man/man3head/types.h.3head file path=usr/share/man/man3head/types32.h.3head +file path=usr/share/man/man3head/uchar.h.3head file path=usr/share/man/man3head/ucontext.h.3head file path=usr/share/man/man3head/uio.h.3head file path=usr/share/man/man3head/ulimit.h.3head diff --git a/usr/src/pkg/manifests/system-library.man3c.inc b/usr/src/pkg/manifests/system-library.man3c.inc index 7317e92fce..ce6056ce82 100644 --- a/usr/src/pkg/manifests/system-library.man3c.inc +++ b/usr/src/pkg/manifests/system-library.man3c.inc @@ -58,6 +58,7 @@ file path=usr/share/man/man3c/bsearch.3c file path=usr/share/man/man3c/bstring.3c file path=usr/share/man/man3c/btowc.3c file path=usr/share/man/man3c/byteorder.3c +file path=usr/share/man/man3c/c16rtomb.3c file path=usr/share/man/man3c/call_once.3c file path=usr/share/man/man3c/catgets.3c file path=usr/share/man/man3c/catopen.3c @@ -234,7 +235,7 @@ file path=usr/share/man/man3c/makedev.3c file path=usr/share/man/man3c/malloc.3c file path=usr/share/man/man3c/mblen.3c file path=usr/share/man/man3c/mbrlen.3c -file path=usr/share/man/man3c/mbrtowc.3c +file path=usr/share/man/man3c/mbrtoc16.3c file path=usr/share/man/man3c/mbsinit.3c file path=usr/share/man/man3c/mbsrtowcs.3c file path=usr/share/man/man3c/mbstowcs.3c @@ -536,7 +537,6 @@ file path=usr/share/man/man3c/wait3.3c file path=usr/share/man/man3c/waitpid.3c file path=usr/share/man/man3c/walkcontext.3c file path=usr/share/man/man3c/wcpcpy.3c -file path=usr/share/man/man3c/wcrtomb.3c file path=usr/share/man/man3c/wcscasecmp.3c file path=usr/share/man/man3c/wcscoll.3c file path=usr/share/man/man3c/wcsdup.3c @@ -722,6 +722,7 @@ link path=usr/share/man/man3c/bind_textdomain_codeset.3c target=gettext.3c link path=usr/share/man/man3c/bindtextdomain.3c target=gettext.3c link path=usr/share/man/man3c/btowc_l.3c target=btowc.3c link path=usr/share/man/man3c/bzero.3c target=bstring.3c +link path=usr/share/man/man3c/c32rtomb.3c target=c16rtomb.3c link path=usr/share/man/man3c/calloc.3c target=malloc.3c link path=usr/share/man/man3c/canonicalize_file_name.3c target=realpath.3c link path=usr/share/man/man3c/catclose.3c target=catopen.3c @@ -1006,7 +1007,9 @@ link path=usr/share/man/man3c/lrand48.3c target=drand48.3c link path=usr/share/man/man3c/major.3c target=makedev.3c link path=usr/share/man/man3c/mblen_l.3c target=mblen.3c link path=usr/share/man/man3c/mbrlen_l.3c target=mbrlen.3c -link path=usr/share/man/man3c/mbrtowc_l.3c target=mbrtowc.3c +link path=usr/share/man/man3c/mbrtoc32.3c target=mbrtoc16.3c +link path=usr/share/man/man3c/mbrtowc.3c target=mbrtoc16.3c +link path=usr/share/man/man3c/mbrtowc_l.3c target=mbrtoc16.3c link path=usr/share/man/man3c/mbsinit_l.3c target=mbsinit.3c link path=usr/share/man/man3c/mbsnrtowcs.3c target=mbsrtowcs.3c link path=usr/share/man/man3c/mbsnrtowcs_l.3c target=mbsrtowcs.3c @@ -1457,7 +1460,8 @@ link path=usr/share/man/man3c/watoi.3c target=wcstol.3c link path=usr/share/man/man3c/watol.3c target=wcstol.3c link path=usr/share/man/man3c/watoll.3c target=wcstol.3c link path=usr/share/man/man3c/wcpncpy.3c target=wcpcpy.3c -link path=usr/share/man/man3c/wcrtomb_l.3c target=wcrtomb.3c +link path=usr/share/man/man3c/wcrtomb.3c target=c16rtomb.3c +link path=usr/share/man/man3c/wcrtomb_l.3c target=c16rtomb.3c link path=usr/share/man/man3c/wcscasecmp_l.3c target=wcscasecmp.3c link path=usr/share/man/man3c/wcscat.3c target=wcstring.3c link path=usr/share/man/man3c/wcschr.3c target=wcstring.3c diff --git a/usr/src/pkg/manifests/system-test-libctest.mf b/usr/src/pkg/manifests/system-test-libctest.mf index 67594901aa..91c272f9b9 100644 --- a/usr/src/pkg/manifests/system-test-libctest.mf +++ b/usr/src/pkg/manifests/system-test-libctest.mf @@ -183,6 +183,8 @@ file path=opt/libc-tests/tests/symbols/symbols_test.$(ARCH64) mode=0555 file path=opt/libc-tests/tests/thread_name mode=0555 file path=opt/libc-tests/tests/timespec_get.32 mode=0555 file path=opt/libc-tests/tests/timespec_get.64 mode=0555 +file path=opt/libc-tests/tests/uchar.32 mode=0555 +file path=opt/libc-tests/tests/uchar.64 mode=0555 file path=opt/libc-tests/tests/wcsncasecmp-7344.32 mode=0555 file path=opt/libc-tests/tests/wcsncasecmp-7344.64 mode=0555 file path=opt/libc-tests/tests/wcsncasecmp-7350.32 mode=0555 diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run index 0af74f8780..e59f1b104e 100644 --- a/usr/src/test/libc-tests/runfiles/default.run +++ b/usr/src/test/libc-tests/runfiles/default.run @@ -112,6 +112,8 @@ timeout = 600 [/opt/libc-tests/tests/thread_name] [/opt/libc-tests/tests/timespec_get.32] [/opt/libc-tests/tests/timespec_get.64] +[/opt/libc-tests/tests/uchar.32] +[/opt/libc-tests/tests/uchar.64] [/opt/libc-tests/tests/pthread_attr_get_np] diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile index 1b7b4723e4..c4db6695ce 100644 --- a/usr/src/test/libc-tests/tests/Makefile +++ b/usr/src/test/libc-tests/tests/Makefile @@ -50,7 +50,8 @@ PROGS = \ timespec_get \ wcsncasecmp \ wcsncasecmp-7344 \ - wcsncasecmp-7350 + wcsncasecmp-7350 \ + uchar SCRIPTS = \ quick_exit \ diff --git a/usr/src/test/libc-tests/tests/uchar.c b/usr/src/test/libc-tests/tests/uchar.c new file mode 100644 index 0000000000..895711fe5e --- /dev/null +++ b/usr/src/test/libc-tests/tests/uchar.c @@ -0,0 +1,789 @@ +/* + * 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 + */ + +/* + * Test the implementation of various pieces of uchar.h(3HEAD) functionality. + */ + +#include <locale.h> +#include <err.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/sysmacros.h> +#include <strings.h> +#include <wchar.h> +#include <uchar.h> +#include <errno.h> + +static const char *uchar_wide = "光"; +static const char32_t uchar_value = 0x5149; +static const char *uchar_hello = "hello"; + +static void +update_locale(const char *loc) +{ + const char *newloc = setlocale(LC_CTYPE, loc); + if (newloc == NULL) { + err(EXIT_FAILURE, "TEST FAILED: failed to update locale to %s", + loc); + } + + if (strcmp(newloc, loc) != 0) { + errx(EXIT_FAILURE, "TEST FAILED: locale set to %s, but got %s", + loc, newloc); + } +} + +static boolean_t +mbrtoc32_ascii(mbstate_t *mbs) +{ + char32_t out; + size_t len; + boolean_t ret = B_TRUE; + + if ((len = mbrtoc32(&out, uchar_hello, 5, mbs)) != 1) { + warnx("expected mbrtoc32 to return 1, returned %zu", len); + ret = B_FALSE; + } + + if (out != 'h') { + warnx("got bad char32_t, expected 0x%x, found 0x%x\n", 'h', + out); + ret = B_FALSE; + } + + if ((len = mbrtoc32(&out, uchar_hello + 1, 4, mbs)) != 1) { + warnx("expected mbrtoc32 to return 1, returned %zu", len); + ret = B_FALSE; + } + + if (out != 'e') { + warnx("got bad char32_t, expected 0x%x, found 0x%x\n", 'h', + out); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc32_ascii_internal(void) +{ + return (mbrtoc32_ascii(NULL)); +} + +static boolean_t +mbrtoc32_ascii_mbstate(void) +{ + mbstate_t mbs; + + bzero(&mbs, sizeof (mbs)); + return (mbrtoc32_ascii(&mbs)); +} + +static boolean_t +mbrtoc32_badseq_utf8(void) +{ + mbstate_t mbs; + size_t len; + char32_t out; + boolean_t ret = B_TRUE; + char *badstr; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc32(&out, "\xa9", 1, &mbs); + if (len != (size_t)-1) { + warnx("mbrtoc32 returned %zu, not %zu", len, (size_t)-1); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("found bad errno, expected %d, found %d\n", errno, + EILSEQ); + ret = B_FALSE; + } + + badstr = strdup(uchar_wide); + if (badstr == NULL) { + warn("failed to duplicate uchar_wide"); + return (B_FALSE); + } + + badstr[1] = '?'; + bzero(&mbs, sizeof (mbs)); + len = mbrtoc32(&out, badstr, strlen(badstr), &mbs); + free(badstr); + if (len != (size_t)-1) { + warnx("mbrtoc32 returned %zu, not %zu", len, (size_t)-1); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("found bad errno, expected %d, found %d\n", errno, + EILSEQ); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc32_roundtrip(void) +{ + char32_t out; + size_t len, clen; + mbstate_t mbs; + char buf[MB_CUR_MAX]; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc32(&out, uchar_wide, strlen(uchar_wide), &mbs); + if (len != 3) { + warnx("mbrtoc32 returned %zu, expected %u", len, 3); + ret = B_FALSE; + } + + if (out != uchar_value) { + warnx("mbrtoc32 converted character to 0x%x not 0x%x", + out, uchar_value); + ret = B_FALSE; + } + + clen = c32rtomb(buf, out, &mbs); + if (clen != len) { + warnx("c32rtomb returned %d bytes, but we originally used %d", + clen, len); + ret = B_FALSE; + } + + if (strncmp(buf, uchar_wide, len) != 0) { + warnx("round trip string comparison failed"); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc32_partial(void) +{ + char32_t out; + size_t len, i; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + for (i = 0; i < strlen(uchar_wide) - 1; i++) { + len = mbrtoc32(&out, uchar_wide + i, 1, &mbs); + if (len != (size_t)-2) { + warnx("partial mbrtoc32 returned %zu, not -2", len); + ret = B_FALSE; + } + } + + len = mbrtoc32(&out, uchar_wide + i, 1, &mbs); + if (len != 1) { + warnx("partial mbrtoc32 returned %zu, not 1", len); + ret = B_FALSE; + } + + if (out != uchar_value) { + warnx("mbrtoc32 converted character to 0x%x not 0x%x", + out, uchar_value); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc32_zero(void) +{ + char32_t out, exp = L'\0'; + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc32(&out, "", 1, &mbs); + if (len != 0) { + warnx("partial mbrtoc32 returned %zu, not 0", len); + ret = B_FALSE; + } + + if (out != exp) { + warnx("mbrtoc32 converted character to 0x%x not 0x%x", + out, exp); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc32_zero_len(void) +{ + char32_t out = 0x12345, exp = 0x12345; + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc32(&out, uchar_wide, 0, &mbs); + if (len != (size_t)-2) { + warnx("partial mbrtoc32 returned %zu, not -2", len); + ret = B_FALSE; + } + + if (out != exp) { + warnx("mbrtoc32 incorrectly wrote to char32_t value with " + "zero string, found 0x%x not 0x%x", out, exp); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc32_null(void) +{ + char32_t out = 0x123456, exp = 0x123456; + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc32(&out, NULL, 1, &mbs); + if (len != 0) { + warnx("partial mbrtoc32 returned %zu, not 0", len); + ret = B_FALSE; + } + + if (out != exp) { + warnx("mbrtoc32 incorrectly wrote to char32_t value with " + "null string, found 0x%x not 0x%x", out, exp); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_ascii(mbstate_t *mbs) +{ + char16_t out; + size_t len; + boolean_t ret = B_TRUE; + + if ((len = mbrtoc16(&out, uchar_hello, 5, mbs)) != 1) { + warnx("expected mbrtoc16 to return 1, returned %zu", len); + ret = B_FALSE; + } + + if (out != 'h') { + warnx("got bad char16_t, expected 0x%x, found 0x%x\n", 'h', + out); + ret = B_FALSE; + } + + if ((len = mbrtoc16(&out, uchar_hello + 1, 4, mbs)) != 1) { + warnx("expected mbrtoc16 to return 1, returned %zu", len); + ret = B_FALSE; + } + + if (out != 'e') { + warnx("got bad char16_t, expected 0x%x, found 0x%x\n", 'h', + out); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_ascii_internal(void) +{ + return (mbrtoc16_ascii(NULL)); +} + +static boolean_t +mbrtoc16_ascii_mbstate(void) +{ + mbstate_t mbs; + + bzero(&mbs, sizeof (mbs)); + return (mbrtoc16_ascii(&mbs)); +} + +static boolean_t +mbrtoc16_null(void) +{ + char16_t out = 0x1234, exp = 0x1234; + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc16(&out, NULL, 1, &mbs); + if (len != 0) { + warnx("partial mbrtoc16 returned %zu, not 0", len); + ret = B_FALSE; + } + + if (out != exp) { + warnx("mbrtoc16 incorrectly wrote to char16_t value with " + "null string, found 0x%x not 0x%x", out, exp); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_zero(void) +{ + char16_t out, exp = L'\0'; + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc16(&out, "", 1, &mbs); + if (len != 0) { + warnx("partial mbrtoc16 returned %zu, not 0", len); + ret = B_FALSE; + } + + if (out != exp) { + warnx("mbrtoc16 converted character to 0x%x not 0x%x", + out, exp); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_zero_len(void) +{ + char16_t out = 0x5432, exp = 0x5432; + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc16(&out, uchar_wide, 0, &mbs); + if (len != (size_t)-2) { + warnx("partial mbrtoc16 returned %zu, not -2", len); + ret = B_FALSE; + } + + if (out != exp) { + warnx("mbrtoc16 incorrectly wrote to char16_t value with " + "zero length string, found 0x%x not 0x%x", out, exp); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_roundtrip(void) +{ + char16_t out; + size_t len, clen; + mbstate_t mbs; + char buf[MB_CUR_MAX]; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc16(&out, uchar_wide, strlen(uchar_wide), &mbs); + if (len != 3) { + warnx("mbrtoc16 returned %zu, expected %u", len, 3); + ret = B_FALSE; + } + + if (out != uchar_value) { + warnx("mbrtoc16 converted character to 0x%x not 0x%x", + out, uchar_value); + ret = B_FALSE; + } + + clen = c16rtomb(buf, out, &mbs); + if (clen != len) { + warnx("c16rtomb returned %d bytes, but we originally used %d", + clen, len); + ret = B_FALSE; + } + + if (strncmp(buf, uchar_wide, len) != 0) { + warnx("round trip string comparison failed"); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_partial(void) +{ + char16_t out; + size_t len, i; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + for (i = 0; i < strlen(uchar_wide) - 1; i++) { + len = mbrtoc16(&out, uchar_wide + i, 1, &mbs); + if (len != (size_t)-2) { + warnx("partial mbrtoc16 returned %zu, not -2", len); + ret = B_FALSE; + } + } + + len = mbrtoc16(&out, uchar_wide + i, 1, &mbs); + if (len != 1) { + warnx("partial mbrtoc16 returned %zu, not 1", len); + ret = B_FALSE; + } + + if (out != uchar_value) { + warnx("mbrtoc16 converted character to 0x%x not 0x%x", + out, uchar_value); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +mbrtoc16_surrogate(void) +{ + char16_t out0, out1; + size_t len, clen; + mbstate_t mbs; + const char *surrogate = "\xF0\x9F\x92\xA9"; + char16_t exp0 = 0xd83d, exp1 = 0xdca9; + size_t slen = strlen(surrogate); + boolean_t ret = B_TRUE; + char buf[MB_CUR_MAX]; + + bzero(&mbs, sizeof (mbs)); + len = mbrtoc16(&out0, surrogate, slen, &mbs); + if (len != slen) { + warnx("mbrtoc16 returned %zu, expected %u", len, slen); + ret = B_FALSE; + } + + if (out0 != exp0) { + warnx("mbrtoc16 converted character to 0x%x not 0x%x", + out0, exp0); + ret = B_FALSE; + } + + if (mbsinit(&mbs) != 0) { + warnx("mb state with a surrogate character is somehow in the " + "initial state"); + ret = B_FALSE; + } + + len = mbrtoc16(&out1, uchar_wide, strlen(uchar_wide), &mbs); + if (len != (size_t)-3) { + warnx("mbrtoc16 returned %zu, expected -3", len); + ret = B_FALSE; + } + + if (mbsinit(&mbs) == 0) { + warnx("mb state with after both surrogate characters isn't " + "in initial state"); + ret = B_FALSE; + } + + if (out1 != exp1) { + warnx("mbrtoc32 converted character to 0x%x not 0x%x", + out1, exp1); + ret = B_FALSE; + } + + clen = c16rtomb(buf, out0, &mbs); + if (clen != 0) { + warnx("c16rtomb returned %d bytes, but expected zero for the " + "first surrogate", clen); + ret = B_FALSE; + } + + if (mbsinit(&mbs) != 0) { + warnx("mb state with a surrogate character is somehow in the " + "initial state"); + ret = B_FALSE; + } + + clen = c16rtomb(buf, out1, &mbs); + if (clen != slen) { + warnx("c16rtomb returned %zd, expected %u", len, slen); + ret = B_FALSE; + } + + if (mbsinit(&mbs) == 0) { + warnx("mb state with after both surrogate characters isn't " + "in initial state"); + ret = B_FALSE; + } + + if (strncmp(buf, surrogate, slen) != 0) { + warnx("round trip string comparison failed"); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +c32rtomb_eilseq_iso8859(void) +{ + char buf[MB_CUR_MAX]; + mbstate_t mbs; + size_t len; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = c32rtomb(buf, uchar_value, &mbs); + if (len != (size_t)-1) { + warnx("c32rtomb returned %zd, expected -1\n", len); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("expected errno set to %d was %d", EILSEQ, errno); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +c16rtomb_eilseq_iso8859(void) +{ + char buf[MB_CUR_MAX]; + mbstate_t mbs; + size_t len; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = c32rtomb(buf, (char16_t)uchar_value, &mbs); + if (len != (size_t)-1) { + warnx("c32rtomb returned %zd, expected -1\n", len); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("expected errno set to %d was %d", EILSEQ, errno); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +c32rtomb_eilseq_utf8(void) +{ + char buf[MB_CUR_MAX]; + mbstate_t mbs; + size_t len; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = c32rtomb(buf, UINT32_MAX, &mbs); + if (len != (size_t)-1) { + warnx("c32rtomb returned %zd, expected -1\n", len); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("expected errno set to %d was %d", EILSEQ, errno); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +c16rtomb_bad_first(void) +{ + char buf[MB_CUR_MAX]; + mbstate_t mbs; + size_t len, i; + char16_t first = 0xd83d; + char16_t bad[] = { 0x0, 0xd7ff, 0xd83d, 0xd900, 0xffff }; + boolean_t ret = B_TRUE; + + for (i = 0; i < ARRAY_SIZE(bad); i++) { + bzero(&mbs, sizeof (mbs)); + len = c16rtomb(buf, first, &mbs); + if (len != 0) { + warnx("c16rtomb returned %zd, expected 0\n", len); + ret = B_FALSE; + } + + len = c16rtomb(buf, bad[i], &mbs); + if (len != (size_t)-1) { + warnx("c16rtomb surrogate %x returned %zd, expected " + "-1\n", bad[i], len); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("expected errno set to %d was %d", EILSEQ, errno); + ret = B_FALSE; + } + } + + return (ret); +} + +static boolean_t +c16rtomb_bad_second(void) +{ + char buf[MB_CUR_MAX]; + mbstate_t mbs; + size_t len, i; + char16_t bad[] = { 0xdc00, 0xdd34, 0xdfff }; + boolean_t ret = B_TRUE; + + for (i = 0; i < ARRAY_SIZE(bad); i++) { + bzero(&mbs, sizeof (mbs)); + len = c16rtomb(buf, bad[i], &mbs); + if (len != (size_t)-1) { + warnx("c16rtomb surrogate %x returned %zd, expected " + "-1\n", bad[i], len); + ret = B_FALSE; + } + + if (errno != EILSEQ) { + warnx("expected errno set to %d was %d", EILSEQ, errno); + ret = B_FALSE; + } + } + + return (ret); +} + +static boolean_t +c32rtomb_null(void) +{ + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = c32rtomb(NULL, uchar_value, &mbs); + if (len != 1) { + warnx("c32rtomb returned %zd, expected %zd", len, 1); + ret = B_FALSE; + } + + return (ret); +} + +static boolean_t +c16rtomb_null(void) +{ + size_t len; + mbstate_t mbs; + boolean_t ret = B_TRUE; + + bzero(&mbs, sizeof (mbs)); + len = c16rtomb(NULL, uchar_value, &mbs); + if (len != 1) { + warnx("c16rtomb returned %zd, expected %zd", len, 1); + ret = B_FALSE; + } + + return (ret); +} + +typedef boolean_t (*uchar_test_f)(void); + +typedef struct uchar_test { + uchar_test_f ut_func; + const char *ut_test; + const char *ut_locale; +} uchar_test_t; + +static const uchar_test_t uchar_tests[] = { + { mbrtoc32_ascii_mbstate, "mbrtoc32: ascii conversion" }, + { mbrtoc32_ascii_internal, "mbrtoc32: ascii conversion (internal " + "mbstate_t)" }, + { mbrtoc32_badseq_utf8, "mbrtoc32: bad locale sequence (UTF-8)" }, + { mbrtoc32_roundtrip, "mbrtoc32: round trip conversion" }, + { mbrtoc32_partial, "mbrtoc32: correctly consume partial sequences" }, + { mbrtoc32_zero, "mbrtoc32: correctly handle L'\\0'" }, + { mbrtoc32_zero_len, "mbrtoc32: correctly handle length of zero" }, + { mbrtoc32_null, "mbrtoc32: correctly handle null string" }, + { mbrtoc16_ascii_mbstate, "mbrtoc16: ascii conversion" }, + { mbrtoc16_ascii_internal, "mbrtoc16: ascii conversion (internal " + "mbstate_t)" }, + { mbrtoc16_null, "mbrtoc16: correctly handle null string" }, + { mbrtoc16_zero, "mbrtoc16: correctly handle L'\\0'" }, + { mbrtoc16_zero_len, "mbrtoc16: correctly handle length of zero" }, + { mbrtoc16_roundtrip, "mbrtoc16: round trip conversion" }, + { mbrtoc16_partial, "mbrtoc16: correctly consume partial sequences" }, + { mbrtoc16_surrogate, "mbrtoc16: correctly generate surrogate pairs " + "and round trip conversion" }, + { c32rtomb_eilseq_iso8859, "c32rtomb: character outside of locale is " + "caught", "en_US.ISO8859-1" }, + { c16rtomb_eilseq_iso8859, "c16rtomb: character outside of locale is " + "caught", "en_US.ISO8859-1" }, + { c32rtomb_eilseq_utf8, "c32rtomb: character outside of locale is " + "caught" }, + { c16rtomb_bad_first, "c16rtomb: bad first surrogate pair" }, + { c16rtomb_bad_second, "c16rtomb: bad second surrogate pair" }, + { c32rtomb_null, "c32rtomb: correctly handle null buffer" }, + { c16rtomb_null, "c16rtomb: correctly handle null buffer" }, +}; + +int +main(void) +{ + uint_t i; + uint_t passes = 0; + uint_t ntests = ARRAY_SIZE(uchar_tests); + + for (i = 0; i < ntests; i++) { + boolean_t r; + + /* + * Default to a standard UTF-8 locale if none is requested by + * the test. + */ + if (uchar_tests[i].ut_locale != NULL) { + update_locale(uchar_tests[i].ut_locale); + } else { + update_locale("en_US.UTF-8"); + } + + r = uchar_tests[i].ut_func(); + (void) fprintf(stderr, "TEST %s: %s\n", r ? "PASSED" : "FAILED", + uchar_tests[i].ut_test); + if (r) { + passes++; + } + } + + (void) printf("%d/%d test%s passed\n", passes, ntests, + passes > 1 ? "s" : ""); + return (passes == ntests ? EXIT_SUCCESS : EXIT_FAILURE); + +} diff --git a/usr/src/uts/common/sys/int_types.h b/usr/src/uts/common/sys/int_types.h index e57d6f8b75..8f7c423643 100644 --- a/usr/src/uts/common/sys/int_types.h +++ b/usr/src/uts/common/sys/int_types.h @@ -173,6 +173,9 @@ typedef long long int_least64_t; #endif #endif +/* + * If these are changed, please update char16_t and char32_t in head/uchar.h. + */ typedef unsigned char uint_least8_t; typedef unsigned short uint_least16_t; typedef unsigned int uint_least32_t; |