summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2015-11-23 08:31:41 +0000
committerngie <ngie@FreeBSD.org>2015-11-23 08:31:41 +0000
commit243e40ca7903af22f673885944979008bd9c7d1d (patch)
tree0f041c18c2452bf663153c190277220b23158463 /lib/libc
parentf531d58e9ae6bdb56f1addaa8c88b692af2c1b67 (diff)
downloadFreeBSD-src-243e40ca7903af22f673885944979008bd9c7d1d.zip
FreeBSD-src-243e40ca7903af22f673885944979008bd9c7d1d.tar.gz
MFC r290532,r290561,r290843,r290844,r290845:
r290532: Integrate tools/regression/lib/libc/locale into the FreeBSD test suite as lib/libc/tests/locale Sponsored by: EMC / Isilon Storage Division r290561: Delete leftover printfs from when these were TAP tests Sponsored by: EMC / Isilon Storage Division r290843: Polish up the tests a bit more after projects/collation was merged to head Provide more meaningful diagnostic messages if LC_CTYPE can't be set properly instead of segfaulting, because setlocale returns NULL and strcmp(NULL, b) will always segfault Split up the testcases so one failing (in this case en_US.ISO8859-15) won't cause the rest of the testcases to be skipped Remove some unused variables Sponsored by: EMC / Isilon Storage Division r290844: Polish up iswctype_test - Split up the testcases into C locale and ja_JP.eucJP testcases. - Avoid a segfault in the event that setlocale fails, similar to r290843 - Replace `sizeof(x) / sizeof(*x)` pattern with `nitems(x)` Sponsored by: EMC / Isilon Storage Division r290845: Remove unused variables; sort by alignment where needed Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/tests/locale/Makefile26
-rw-r--r--lib/libc/tests/locale/btowc_test.c71
-rw-r--r--lib/libc/tests/locale/c16rtomb_test.c166
-rw-r--r--lib/libc/tests/locale/iswctype_test.c122
-rw-r--r--lib/libc/tests/locale/mblen_test.c116
-rw-r--r--lib/libc/tests/locale/mbrlen_test.c126
-rw-r--r--lib/libc/tests/locale/mbrtoc16_test.c214
-rw-r--r--lib/libc/tests/locale/mbrtowc_test.c165
-rw-r--r--lib/libc/tests/locale/mbsnrtowcs_test.c195
-rw-r--r--lib/libc/tests/locale/mbsrtowcs_test.c153
-rw-r--r--lib/libc/tests/locale/mbstowcs_test.c111
-rw-r--r--lib/libc/tests/locale/mbtowc_test.c122
-rw-r--r--lib/libc/tests/locale/towctrans_test.c90
-rw-r--r--lib/libc/tests/locale/wcrtomb_test.c135
-rw-r--r--lib/libc/tests/locale/wcsnrtombs_test.c195
-rw-r--r--lib/libc/tests/locale/wcsrtombs_test.c156
-rw-r--r--lib/libc/tests/locale/wcstombs_test.c130
-rw-r--r--lib/libc/tests/locale/wctomb_test.c113
18 files changed, 2405 insertions, 1 deletions
diff --git a/lib/libc/tests/locale/Makefile b/lib/libc/tests/locale/Makefile
index e4dc553..d15fd5e 100644
--- a/lib/libc/tests/locale/Makefile
+++ b/lib/libc/tests/locale/Makefile
@@ -4,6 +4,24 @@
TESTSDIR= ${TESTSBASE}/lib/libc/locale
+ATF_TESTS_C+= btowc_test
+ATF_TESTS_C+= c16rtomb_test
+ATF_TESTS_C+= iswctype_test
+ATF_TESTS_C+= mblen_test
+ATF_TESTS_C+= mbrlen_test
+ATF_TESTS_C+= mbrtoc16_test
+ATF_TESTS_C+= mbrtowc_2_test
+ATF_TESTS_C+= mbsnrtowcs_2_test
+ATF_TESTS_C+= mbsrtowcs_test
+ATF_TESTS_C+= mbstowcs_2_test
+ATF_TESTS_C+= mbtowc_2_test
+ATF_TESTS_C+= towctrans_test
+ATF_TESTS_C+= wcrtomb_test
+ATF_TESTS_C+= wcsnrtombs_test
+ATF_TESTS_C+= wcsrtombs_test
+ATF_TESTS_C+= wcstombs_test
+ATF_TESTS_C+= wctomb_2_test
+
NETBSD_ATF_TESTS_C= io_test
NETBSD_ATF_TESTS_C+= mbrtowc_test
NETBSD_ATF_TESTS_C+= mbstowcs_test
@@ -15,7 +33,13 @@ NETBSD_ATF_TESTS_C+= wcsspn_test
NETBSD_ATF_TESTS_C+= wcstod_test
NETBSD_ATF_TESTS_C+= wctomb_test
-CFLAGS.t_wctomb.c+= -Wno-stack-protector
+SRCS.mbrtowc_2_test= mbrtowc_test.c
+SRCS.mbsnrtowcs_2_test= mbsnrtowcs_test.c
+SRCS.mbstowcs_2_test= mbstowcs_test.c
+SRCS.mbtowc_2_test= mbtowc_test.c
+SRCS.wctomb_2_test= wctomb_test.c
+
+CFLAGS.t_wctomb.c+= -Wno-stack-protector
.include "../Makefile.netbsd-tests"
diff --git a/lib/libc/tests/locale/btowc_test.c b/lib/libc/tests/locale/btowc_test.c
new file mode 100644
index 0000000..01a1133
--- /dev/null
+++ b/lib/libc/tests/locale/btowc_test.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for btowc() and wctob() as specified by IEEE Std. 1003.1-2001
+ * and ISO/IEC 9899:1999.
+ *
+ * The function is tested in the "C" and "ja_JP.eucJP" locales.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(btowc_test);
+ATF_TC_BODY(btowc_test, tc)
+{
+ int i;
+
+ /* C/POSIX locale. */
+ ATF_REQUIRE(btowc(EOF) == WEOF);
+ ATF_REQUIRE(wctob(WEOF) == EOF);
+ for (i = 0; i < UCHAR_MAX; i++)
+ ATF_REQUIRE(btowc(i) == (wchar_t)i && i == (int)wctob(i));
+
+ /* Japanese (EUC) locale. */
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+ ATF_REQUIRE(btowc('A') == L'A' && wctob(L'A') == 'A');
+ ATF_REQUIRE(btowc(0xa3) == WEOF && wctob(0xa3c1) == EOF);
+
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, btowc_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/c16rtomb_test.c b/lib/libc/tests/locale/c16rtomb_test.c
new file mode 100644
index 0000000..ea1f64f
--- /dev/null
+++ b/lib/libc/tests/locale/c16rtomb_test.c
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Copyright (c) 2013 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Test program for c16rtomb() as specified by ISO/IEC 9899:2011.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <uchar.h>
+
+#include <atf-c.h>
+
+static void
+require_lc_ctype(const char *locale_name)
+{
+ char *lc_ctype_set;
+
+ lc_ctype_set = setlocale(LC_CTYPE, locale_name);
+ if (lc_ctype_set == NULL)
+ atf_tc_fail("setlocale(LC_CTYPE, \"%s\") failed; errno=%d",
+ locale_name, errno);
+
+ ATF_REQUIRE(strcmp(lc_ctype_set, locale_name) == 0);
+}
+
+static mbstate_t s;
+static char buf[MB_LEN_MAX + 1];
+
+ATF_TC_WITHOUT_HEAD(c16rtomb_c_locale_test);
+ATF_TC_BODY(c16rtomb_c_locale_test, tc)
+{
+
+ require_lc_ctype("C");
+
+ /*
+ * If the buffer argument is NULL, c16 is implicitly 0,
+ * c16rtomb() resets its internal state.
+ */
+ ATF_REQUIRE(c16rtomb(NULL, L'\0', NULL) == 1);
+ ATF_REQUIRE(c16rtomb(NULL, 0xdc00, NULL) == 1);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0, &s) == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(c16rtomb(NULL, L'\0', NULL) == 1);
+ ATF_REQUIRE(c16rtomb(NULL, L'A', NULL) == 1);
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, L'A', &s) == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
+
+ /* Unicode character 'Pile of poo'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
+ ATF_REQUIRE(c16rtomb(buf, 0xdca9, &s) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
+}
+
+ATF_TC_WITHOUT_HEAD(c16rtomb_iso_8859_1_test);
+ATF_TC_BODY(c16rtomb_iso_8859_1_test, tc)
+{
+
+ require_lc_ctype("en_US.ISO8859-1");
+
+ /* Unicode character 'Euro sign'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0x20ac, &s) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
+}
+
+ATF_TC_WITHOUT_HEAD(c16rtomb_iso_8859_15_test);
+ATF_TC_BODY(c16rtomb_iso_8859_15_test, tc)
+{
+
+ require_lc_ctype("en_US.ISO8859-15");
+
+ /* Unicode character 'Euro sign'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0x20ac, &s) == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xa4 && (unsigned char)buf[1] == 0xcc);
+}
+
+ATF_TC_WITHOUT_HEAD(c16rtomb_utf_8_test);
+ATF_TC_BODY(c16rtomb_utf_8_test, tc)
+{
+
+ require_lc_ctype("en_US.UTF-8");
+
+ /* Unicode character 'Pile of poo'. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
+ ATF_REQUIRE(c16rtomb(buf, 0xdca9, &s) == 4);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xf0 && (unsigned char)buf[1] == 0x9f &&
+ (unsigned char)buf[2] == 0x92 && (unsigned char)buf[3] == 0xa9 &&
+ (unsigned char)buf[4] == 0xcc);
+
+ /* Invalid code; 'Pile of poo' without the trail surrogate. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
+ ATF_REQUIRE(c16rtomb(buf, L'A', &s) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
+
+ /* Invalid code; 'Pile of poo' without the lead surrogate. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0xdca9, &s) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, c16rtomb_c_locale_test);
+ ATF_TP_ADD_TC(tp, c16rtomb_iso_8859_1_test);
+ ATF_TP_ADD_TC(tp, c16rtomb_iso_8859_15_test);
+ ATF_TP_ADD_TC(tp, c16rtomb_utf_8_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/iswctype_test.c b/lib/libc/tests/locale/iswctype_test.c
new file mode 100644
index 0000000..14e57b4
--- /dev/null
+++ b/lib/libc/tests/locale/iswctype_test.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2003 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wctype() and iswctype() as specified by
+ * IEEE Std. 1003.1-2001 and ISO/IEC 9899:1999.
+ *
+ * The functions are tested in the "C" and "ja_JP.eucJP" locales.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <atf-c.h>
+
+static void
+require_lc_ctype(const char *locale_name)
+{
+ char *lc_ctype_set;
+
+ lc_ctype_set = setlocale(LC_CTYPE, locale_name);
+ if (lc_ctype_set == NULL)
+ atf_tc_fail("setlocale(LC_CTYPE, \"%s\") failed; errno=%d",
+ locale_name, errno);
+
+ ATF_REQUIRE(strcmp(lc_ctype_set, locale_name) == 0);
+}
+
+static wctype_t t;
+static int i, j;
+static struct {
+ const char *name;
+ int (*func)(wint_t);
+} cls[] = {
+ { "alnum", iswalnum },
+ { "alpha", iswalpha },
+ { "blank", iswblank },
+ { "cntrl", iswcntrl },
+ { "digit", iswdigit },
+ { "graph", iswgraph },
+ { "lower", iswlower },
+ { "print", iswprint },
+ { "punct", iswpunct },
+ { "space", iswspace },
+ { "upper", iswupper },
+ { "xdigit", iswxdigit }
+};
+
+ATF_TC_WITHOUT_HEAD(iswctype_c_locale_test);
+ATF_TC_BODY(iswctype_c_locale_test, tc)
+{
+
+ require_lc_ctype("C");
+ for (i = 0; i < nitems(cls); i++) {
+ t = wctype(cls[i].name);
+ ATF_REQUIRE(t != 0);
+ for (j = 0; j < 256; j++)
+ ATF_REQUIRE(cls[i].func(j) == iswctype(j, t));
+ }
+ t = wctype("elephant");
+ ATF_REQUIRE(t == 0);
+ for (i = 0; i < 256; i++)
+ ATF_REQUIRE(iswctype(i, t) == 0);
+}
+
+ATF_TC_WITHOUT_HEAD(iswctype_euc_jp_test);
+ATF_TC_BODY(iswctype_euc_jp_test, tc)
+{
+
+ require_lc_ctype("ja_JP.eucJP");
+
+ for (i = 0; i < nitems(cls); i++) {
+ t = wctype(cls[i].name);
+ ATF_REQUIRE(t != 0);
+ for (j = 0; j < 65536; j++)
+ ATF_REQUIRE(cls[i].func(j) == iswctype(j, t));
+ }
+ t = wctype("elephant");
+ ATF_REQUIRE(t == 0);
+ for (i = 0; i < 65536; i++)
+ ATF_REQUIRE(iswctype(i, t) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, iswctype_c_locale_test);
+ ATF_TP_ADD_TC(tp, iswctype_euc_jp_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mblen_test.c b/lib/libc/tests/locale/mblen_test.c
new file mode 100644
index 0000000..fbb938d
--- /dev/null
+++ b/lib/libc/tests/locale/mblen_test.c
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mblen(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1990.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mblen_test);
+ATF_TC_BODY(mblen_test, tc)
+{
+ char buf[MB_LEN_MAX + 1];
+
+ /*
+ * C/POSIX locale.
+ */
+
+ ATF_REQUIRE(MB_CUR_MAX == 1);
+
+ /* No shift states in C locale. */
+ ATF_REQUIRE(mblen(NULL, 0) == 0);
+
+ /* Null wide character. */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = '\0';
+ ATF_REQUIRE(mblen(buf, 1) == 0);
+
+ /* Latin letter A. */
+ buf[0] = 'A';
+ ATF_REQUIRE(mblen(buf, 1) == 1);
+
+ /* Incomplete character sequence. */
+ buf[0] = '\0';
+ ATF_REQUIRE(mblen(buf, 0) == -1);
+ ATF_REQUIRE(mblen(NULL, 0) == 0);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ /* No shift states in EUC. */
+ ATF_REQUIRE(mblen(NULL, 0) == 0);
+
+ /* Null wide character. */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = '\0';
+ ATF_REQUIRE(mblen(buf, 1) == 0);
+
+ /* Latin letter A. */
+ buf[0] = 'A';
+ ATF_REQUIRE(mblen(buf, 1) == 1);
+
+ /* Incomplete character sequence. */
+ buf[0] = '\0';
+ ATF_REQUIRE(mblen(buf, 0) == -1);
+ ATF_REQUIRE(mblen(NULL, 0) == 0);
+
+ /* Incomplete character sequence (truncated double-byte). */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0xa3;
+ buf[1] = 0x00;
+ ATF_REQUIRE(mblen(buf, 1) == -1);
+ ATF_REQUIRE(mblen(NULL, 0) == 0);
+
+ /* Same as above, but complete. */
+ buf[1] = 0xc1;
+ ATF_REQUIRE(mblen(buf, 2) == 2);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mblen_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbrlen_test.c b/lib/libc/tests/locale/mbrlen_test.c
new file mode 100644
index 0000000..c2bc548
--- /dev/null
+++ b/lib/libc/tests/locale/mbrlen_test.c
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mbrlen(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mbrlen_test);
+ATF_TC_BODY(mbrlen_test, tc)
+{
+ mbstate_t s;
+ char buf[MB_LEN_MAX + 1];
+
+ /* C/POSIX locale. */
+ ATF_REQUIRE(MB_CUR_MAX == 1);
+
+ /* Null wide character, internal state. */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0;
+ ATF_REQUIRE(mbrlen(buf, 1, NULL) == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 1, &s) == 0);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(mbrlen(NULL, 0, NULL) == 0);
+ buf[0] = 'A';
+ ATF_REQUIRE(mbrlen(buf, 1, NULL) == 1);
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 1, &s) == 1);
+
+ /* Incomplete character sequence. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 0, &s) == (size_t)-2);
+
+ /* Japanese (EUC) locale. */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ /* Null wide character, internal state. */
+ ATF_REQUIRE(mbrlen(NULL, 0, NULL) == 0);
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0;
+ ATF_REQUIRE(mbrlen(buf, 1, NULL) == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 1, &s) == 0);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(mbrlen(NULL, 0, NULL) == 0);
+ buf[0] = 'A';
+ ATF_REQUIRE(mbrlen(buf, 1, NULL) == 1);
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 1, &s) == 1);
+
+ /* Incomplete character sequence (zero length). */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 0, &s) == (size_t)-2);
+
+ /* Incomplete character sequence (truncated double-byte). */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0xa3;
+ buf[1] = 0x00;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 1, &s) == (size_t)-2);
+
+ /* Same as above, but complete. */
+ buf[1] = 0xc1;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrlen(buf, 2, &s) == 2);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbrlen_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbrtoc16_test.c b/lib/libc/tests/locale/mbrtoc16_test.c
new file mode 100644
index 0000000..a6289e1
--- /dev/null
+++ b/lib/libc/tests/locale/mbrtoc16_test.c
@@ -0,0 +1,214 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Copyright (c) 2013 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Test program for mbrtoc16() as specified by ISO/IEC 9899:2011.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <uchar.h>
+
+#include <atf-c.h>
+
+static void
+require_lc_ctype(const char *locale_name)
+{
+ char *lc_ctype_set;
+
+ lc_ctype_set = setlocale(LC_CTYPE, locale_name);
+ if (lc_ctype_set == NULL)
+ atf_tc_fail("setlocale(LC_CTYPE, \"%s\") failed; errno=%d",
+ locale_name, errno);
+
+ ATF_REQUIRE(strcmp(lc_ctype_set, locale_name) == 0);
+}
+
+static mbstate_t s;
+static char16_t c16;
+
+ATF_TC_WITHOUT_HEAD(mbrtoc16_c_locale_test);
+ATF_TC_BODY(mbrtoc16_c_locale_test, tc)
+{
+
+ require_lc_ctype("C");
+
+ /* Null wide character, internal state. */
+ ATF_REQUIRE(mbrtoc16(&c16, "", 1, NULL) == 0);
+ ATF_REQUIRE(c16 == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "", 1, &s) == 0);
+ ATF_REQUIRE(c16 == 0);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(mbrtoc16(NULL, 0, 0, NULL) == 0);
+ ATF_REQUIRE(mbrtoc16(&c16, "A", 1, NULL) == 1);
+ ATF_REQUIRE(c16 == L'A');
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "A", 1, &s) == 1);
+ ATF_REQUIRE(c16 == L'A');
+
+ /* Incomplete character sequence. */
+ c16 = L'z';
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "", 0, &s) == (size_t)-2);
+ ATF_REQUIRE(c16 == L'z');
+
+ /* Check that mbrtoc16() doesn't access the buffer when n == 0. */
+ c16 = L'z';
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "", 0, &s) == (size_t)-2);
+ ATF_REQUIRE(c16 == L'z');
+
+ /* Check that mbrtoc16() doesn't read ahead too aggressively. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "AB", 2, &s) == 1);
+ ATF_REQUIRE(c16 == L'A');
+ ATF_REQUIRE(mbrtoc16(&c16, "C", 1, &s) == 1);
+ ATF_REQUIRE(c16 == L'C');
+
+}
+
+ATF_TC_WITHOUT_HEAD(mbrtoc16_iso_8859_1_test);
+ATF_TC_BODY(mbrtoc16_iso_8859_1_test, tc)
+{
+
+ require_lc_ctype("en_US.ISO8859-1");
+
+ /* Currency sign. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "\xa4", 1, &s) == 1);
+ ATF_REQUIRE(c16 == 0xa4);
+}
+
+ATF_TC_WITHOUT_HEAD(mbrtoc16_iso_8859_15_test);
+ATF_TC_BODY(mbrtoc16_iso_8859_15_test, tc)
+{
+
+ require_lc_ctype("en_US.ISO8859-15");
+
+ /* Euro sign. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "\xa4", 1, &s) == 1);
+ ATF_REQUIRE(c16 == 0x20ac);
+}
+
+ATF_TC_WITHOUT_HEAD(mbrtoc16_utf_8_test);
+ATF_TC_BODY(mbrtoc16_utf_8_test, tc)
+{
+
+ require_lc_ctype("en_US.UTF-8");
+
+ /* Null wide character, internal state. */
+ ATF_REQUIRE(mbrtoc16(NULL, 0, 0, NULL) == 0);
+ ATF_REQUIRE(mbrtoc16(&c16, "", 1, NULL) == 0);
+ ATF_REQUIRE(c16 == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "", 1, &s) == 0);
+ ATF_REQUIRE(c16 == 0);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(mbrtoc16(NULL, 0, 0, NULL) == 0);
+ ATF_REQUIRE(mbrtoc16(&c16, "A", 1, NULL) == 1);
+ ATF_REQUIRE(c16 == L'A');
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "A", 1, &s) == 1);
+ ATF_REQUIRE(c16 == L'A');
+
+ /* Incomplete character sequence (zero length). */
+ c16 = L'z';
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "", 0, &s) == (size_t)-2);
+ ATF_REQUIRE(c16 == L'z');
+
+ /* Incomplete character sequence (truncated double-byte). */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xc3", 1, &s) == (size_t)-2);
+
+ /* Same as above, but complete. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xc3\x84", 2, &s) == 2);
+ ATF_REQUIRE(c16 == 0xc4);
+
+ /* Test restarting behaviour. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xc3", 1, &s) == (size_t)-2);
+ ATF_REQUIRE(c16 == 0);
+ ATF_REQUIRE(mbrtoc16(&c16, "\xb7", 1, &s) == 1);
+ ATF_REQUIRE(c16 == 0xf7);
+
+ /* Surrogate pair. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xf0\x9f\x92\xa9", 4, &s) == 4);
+ ATF_REQUIRE(c16 == 0xd83d);
+ ATF_REQUIRE(mbrtoc16(&c16, "", 0, &s) == (size_t)-3);
+ ATF_REQUIRE(c16 == 0xdca9);
+
+ /* Letter e with acute, precomposed. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xc3\xa9", 2, &s) == 2);
+ ATF_REQUIRE(c16 == 0xe9);
+
+ /* Letter e with acute, combined. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\x65\xcc\x81", 3, &s) == 1);
+ ATF_REQUIRE(c16 == 0x65);
+ ATF_REQUIRE(mbrtoc16(&c16, "\xcc\x81", 2, &s) == 2);
+ ATF_REQUIRE(c16 == 0x301);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbrtoc16_c_locale_test);
+ ATF_TP_ADD_TC(tp, mbrtoc16_iso_8859_1_test);
+ ATF_TP_ADD_TC(tp, mbrtoc16_iso_8859_15_test);
+ ATF_TP_ADD_TC(tp, mbrtoc16_utf_8_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbrtowc_test.c b/lib/libc/tests/locale/mbrtowc_test.c
new file mode 100644
index 0000000..37e0bfd
--- /dev/null
+++ b/lib/libc/tests/locale/mbrtowc_test.c
@@ -0,0 +1,165 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mbrtowc(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mbrtowc_test);
+ATF_TC_BODY(mbrtowc_test, tc)
+{
+ mbstate_t s;
+ wchar_t wc;
+ char buf[MB_LEN_MAX + 1];
+
+ /*
+ * C/POSIX locale.
+ */
+
+ ATF_REQUIRE(MB_CUR_MAX == 1);
+
+ /* Null wide character, internal state. */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0;
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, NULL) == 0);
+ ATF_REQUIRE(wc == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == 0);
+ ATF_REQUIRE(wc == 0);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(mbrtowc(NULL, 0, 0, NULL) == 0);
+ buf[0] = 'A';
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, NULL) == 1);
+ ATF_REQUIRE(wc == L'A');
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == 1);
+ ATF_REQUIRE(wc == L'A');
+
+ /* Incomplete character sequence. */
+ wc = L'z';
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtowc(&wc, buf, 0, &s) == (size_t)-2);
+ ATF_REQUIRE(wc == L'z');
+
+ /* Check that mbrtowc() doesn't access the buffer when n == 0. */
+ wc = L'z';
+ memset(&s, 0, sizeof(s));
+ buf[0] = '\0';
+ ATF_REQUIRE(mbrtowc(&wc, buf, 0, &s) == (size_t)-2);
+ ATF_REQUIRE(wc == L'z');
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ /* Null wide character, internal state. */
+ ATF_REQUIRE(mbrtowc(NULL, 0, 0, NULL) == 0);
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0;
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, NULL) == 0);
+ ATF_REQUIRE(wc == 0);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == 0);
+ ATF_REQUIRE(wc == 0);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(mbrtowc(NULL, 0, 0, NULL) == 0);
+ buf[0] = 'A';
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, NULL) == 1);
+ ATF_REQUIRE(wc == L'A');
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == 1);
+ ATF_REQUIRE(wc == L'A');
+
+ /* Incomplete character sequence (zero length). */
+ wc = L'z';
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtowc(&wc, buf, 0, &s) == (size_t)-2);
+ ATF_REQUIRE(wc == L'z');
+
+ /* Incomplete character sequence (truncated double-byte). */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0xa3;
+ buf[1] = 0x00;
+ memset(&s, 0, sizeof(s));
+ wc = 0;
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == (size_t)-2);
+
+ /* Same as above, but complete. */
+ buf[1] = 0xc1;
+ memset(&s, 0, sizeof(s));
+ wc = 0;
+ ATF_REQUIRE(mbrtowc(&wc, buf, 2, &s) == 2);
+ ATF_REQUIRE(wc == 0xa3c1);
+
+ /* Test restarting behaviour. */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0xa3;
+ memset(&s, 0, sizeof(s));
+ wc = 0;
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == (size_t)-2);
+ ATF_REQUIRE(wc == 0);
+ buf[0] = 0xc1;
+ ATF_REQUIRE(mbrtowc(&wc, buf, 1, &s) == 1);
+ ATF_REQUIRE(wc == 0xa3c1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbrtowc_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbsnrtowcs_test.c b/lib/libc/tests/locale/mbsnrtowcs_test.c
new file mode 100644
index 0000000..4012b7e
--- /dev/null
+++ b/lib/libc/tests/locale/mbsnrtowcs_test.c
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mbsnrtowcs().
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mbsnrtowcs_test);
+ATF_TC_BODY(mbsnrtowcs_test, tc)
+{
+ char srcbuf[128];
+ wchar_t dstbuf[128];
+ char *src;
+ mbstate_t s;
+
+ /* C/POSIX locale. */
+
+ /* Simple null terminated string. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 5);
+ ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
+ ATF_REQUIRE(dstbuf[6] == 0xcccc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Simple null terminated string, stopping early. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 4, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 4);
+ ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
+ ATF_REQUIRE(dstbuf[5] == 0xcccc);
+ ATF_REQUIRE(src == srcbuf + 4);
+
+ /* Not enough space in destination buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, 4, &s) == 4);
+ ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
+ ATF_REQUIRE(dstbuf[5] == 0xcccc);
+ ATF_REQUIRE(src == srcbuf + 4);
+
+ /* Null terminated string, internal dest. buffer */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 6, 0, &s) == 5);
+
+ /* Null terminated string, internal dest. buffer, stopping early */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 4, 0, &s) == 4);
+
+ /* Null terminated string, internal state. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
+ sizeof(*dstbuf), NULL) == 5);
+ ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
+ ATF_REQUIRE(dstbuf[6] == 0xcccc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Null terminated string, internal state, internal dest. buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ ATF_REQUIRE(mbsnrtowcs(NULL, (const char **)&src, 6, 0, NULL) == 5);
+
+ /* Empty source buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ srcbuf[0] = '\0';
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, 1, &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0);
+ ATF_REQUIRE(dstbuf[1] == 0xcccc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Zero length destination buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, 0, &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0xcccc);
+ ATF_REQUIRE(src == srcbuf);
+
+ /* Zero length source buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 0, 1, &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0xcccc);
+ ATF_REQUIRE(src == srcbuf);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 8, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 5);
+ ATF_REQUIRE(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
+ dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
+ ATF_REQUIRE(src == NULL);
+
+ /* Partial character. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 4);
+ ATF_REQUIRE(src == srcbuf + 6);
+ ATF_REQUIRE(!mbsinit(&s));
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 1);
+ ATF_REQUIRE(src == srcbuf + 7);
+ ATF_REQUIRE(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 0);
+ ATF_REQUIRE(src == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbsnrtowcs_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbsrtowcs_test.c b/lib/libc/tests/locale/mbsrtowcs_test.c
new file mode 100644
index 0000000..1b9d5c9
--- /dev/null
+++ b/lib/libc/tests/locale/mbsrtowcs_test.c
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mbsrtowcs(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mbsrtowcs_test);
+ATF_TC_BODY(mbsrtowcs_test, tc)
+{
+ char srcbuf[128];
+ wchar_t dstbuf[128];
+ char *src;
+ mbstate_t s;
+
+ /*
+ * C/POSIX locale.
+ */
+
+ /* Simple null terminated string. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsrtowcs(dstbuf, (const char **)&src, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 5);
+ ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
+ ATF_REQUIRE(dstbuf[6] == 0xcccc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Not enough space in destination buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsrtowcs(dstbuf, (const char **)&src, 4, &s) == 4);
+ ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
+ ATF_REQUIRE(dstbuf[5] == 0xcccc);
+ ATF_REQUIRE(src == srcbuf + 4);
+
+ /* Null terminated string, internal dest. buffer */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbsrtowcs(NULL, (const char **)&src, 0, &s) == 5);
+
+ /* Null terminated string, internal state. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ src = srcbuf;
+ ATF_REQUIRE(mbsrtowcs(dstbuf, (const char **)&src, sizeof(dstbuf) /
+ sizeof(*dstbuf), NULL) == 5);
+ ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
+ ATF_REQUIRE(dstbuf[6] == 0xcccc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Null terminated string, internal state, internal dest. buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ ATF_REQUIRE(mbsrtowcs(NULL, (const char **)&src, 0, NULL) == 5);
+
+ /* Empty source buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ srcbuf[0] = '\0';
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsrtowcs(dstbuf, (const char **)&src, 1, &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0);
+ ATF_REQUIRE(dstbuf[1] == 0xcccc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Zero length destination buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsrtowcs(dstbuf, (const char **)&src, 0, &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0xcccc);
+ ATF_REQUIRE(src == srcbuf);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbsrtowcs(dstbuf, (const char **)&src, sizeof(dstbuf) /
+ sizeof(*dstbuf), &s) == 5);
+ ATF_REQUIRE(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
+ dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
+ ATF_REQUIRE(src == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbsrtowcs_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbstowcs_test.c b/lib/libc/tests/locale/mbstowcs_test.c
new file mode 100644
index 0000000..77b0e9e
--- /dev/null
+++ b/lib/libc/tests/locale/mbstowcs_test.c
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mbstowcs(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mbstowcs_test);
+ATF_TC_BODY(mbstowcs_test, tc)
+{
+ char srcbuf[128];
+ wchar_t dstbuf[128];
+
+ /* C/POSIX locale. */
+
+ /* Simple null terminated string. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbstowcs(dstbuf, srcbuf, sizeof(dstbuf) / sizeof(*dstbuf)) == 5);
+ ATF_REQUIRE(wcscmp(dstbuf, L"hello") == 0);
+ ATF_REQUIRE(dstbuf[6] == 0xcccc);
+
+ /* Not enough space in destination buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbstowcs(dstbuf, srcbuf, 4) == 4);
+ ATF_REQUIRE(wmemcmp(dstbuf, L"hell", 4) == 0);
+ ATF_REQUIRE(dstbuf[5] == 0xcccc);
+
+ /* Null terminated string, internal dest. buffer (XSI extension) */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ ATF_REQUIRE(mbstowcs(NULL, srcbuf, 0) == 5);
+
+ /* Empty source buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ srcbuf[0] = '\0';
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbstowcs(dstbuf, srcbuf, 1) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0);
+ ATF_REQUIRE(dstbuf[1] == 0xcccc);
+
+ /* Zero length destination buffer. */
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "hello");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbstowcs(dstbuf, srcbuf, 0) == 0);
+ ATF_REQUIRE(dstbuf[0] == 0xcccc);
+
+ /* Japanese (EUC) locale. */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ memset(srcbuf, 0xcc, sizeof(srcbuf));
+ strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
+ wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
+ ATF_REQUIRE(mbstowcs(dstbuf, srcbuf, sizeof(dstbuf) / sizeof(*dstbuf)) == 5);
+ ATF_REQUIRE(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
+ dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbstowcs_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/mbtowc_test.c b/lib/libc/tests/locale/mbtowc_test.c
new file mode 100644
index 0000000..7c7f80e
--- /dev/null
+++ b/lib/libc/tests/locale/mbtowc_test.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for mbtowc(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1990.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(mbtowc_test);
+ATF_TC_BODY(mbtowc_test, tc)
+{
+ char buf[MB_LEN_MAX + 1];
+ wchar_t wc;
+
+ /* C/POSIX locale. */
+
+ ATF_REQUIRE(MB_CUR_MAX == 1);
+
+ /* No shift states in C locale. */
+ ATF_REQUIRE(mbtowc(NULL, NULL, 0) == 0);
+
+ /* Null wide character. */
+ wc = 0xcccc;
+ memset(buf, 0, sizeof(buf));
+ ATF_REQUIRE(mbtowc(&wc, buf, 1) == 0);
+ ATF_REQUIRE(wc == 0);
+
+ /* Latin letter A. */
+ buf[0] = 'A';
+ ATF_REQUIRE(mbtowc(&wc, buf, 1) == 1);
+ ATF_REQUIRE(wc == L'A');
+
+ /* Incomplete character sequence. */
+ wc = L'z';
+ buf[0] = '\0';
+ ATF_REQUIRE(mbtowc(&wc, buf, 0) == -1);
+ ATF_REQUIRE(wc == L'z');
+ ATF_REQUIRE(mbtowc(NULL, NULL, 0) == 0);
+
+ /* Japanese (EUC) locale. */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ /* Null wide character */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0;
+ wc = 0xcccc;
+ ATF_REQUIRE(mbtowc(&wc, buf, 1) == 0);
+ ATF_REQUIRE(wc == 0);
+
+ /* Latin letter A. */
+ buf[0] = 'A';
+ ATF_REQUIRE(mbtowc(&wc, buf, 1) == 1);
+ ATF_REQUIRE(wc == L'A');
+
+ /* Incomplete character sequence (zero length). */
+ wc = L'z';
+ buf[0] = '\0';
+ ATF_REQUIRE(mbtowc(&wc, buf, 0) == -1);
+ ATF_REQUIRE(wc == L'z');
+ ATF_REQUIRE(mbtowc(NULL, NULL, 0) == 0);
+
+ /* Incomplete character sequence (truncated double-byte). */
+ memset(buf, 0xcc, sizeof(buf));
+ buf[0] = 0xa3;
+ buf[1] = 0x00;
+ wc = L'z';
+ ATF_REQUIRE(mbtowc(&wc, buf, 1) == -1);
+ ATF_REQUIRE(wc == L'z');
+ ATF_REQUIRE(mbtowc(NULL, NULL, 0) == 0);
+
+ /* Same as above, but complete. */
+ buf[1] = 0xc1;
+ ATF_REQUIRE(mbtowc(&wc, buf, 2) == 2);
+ ATF_REQUIRE(wc == 0xa3c1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbtowc_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/towctrans_test.c b/lib/libc/tests/locale/towctrans_test.c
new file mode 100644
index 0000000..bb9d97c
--- /dev/null
+++ b/lib/libc/tests/locale/towctrans_test.c
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2003 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wctrans() and towctrans() as specified by
+ * IEEE Std. 1003.1-2001 and ISO/IEC 9899:1999.
+ *
+ * The functions are tested in the "C" and "ja_JP.eucJP" locales.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(towctrans_test);
+ATF_TC_BODY(towctrans_test, tc)
+{
+ wctype_t t;
+ int i, j;
+ struct {
+ const char *name;
+ wint_t (*func)(wint_t);
+ } tran[] = {
+ { "tolower", towlower },
+ { "toupper", towupper },
+ };
+
+ /* C/POSIX locale. */
+ for (i = 0; i < sizeof(tran) / sizeof(*tran); i++) {
+ t = wctrans(tran[i].name);
+ ATF_REQUIRE(t != 0);
+ for (j = 0; j < 256; j++)
+ ATF_REQUIRE(tran[i].func(j) == towctrans(j, t));
+ }
+ t = wctrans("elephant");
+ ATF_REQUIRE(t == 0);
+ for (i = 0; i < 256; i++)
+ ATF_REQUIRE(towctrans(i, t) == i);
+
+ /* Japanese (EUC) locale. */
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ for (i = 0; i < sizeof(tran) / sizeof(*tran); i++) {
+ t = wctrans(tran[i].name);
+ ATF_REQUIRE(t != 0);
+ for (j = 0; j < 65536; j++)
+ ATF_REQUIRE(tran[i].func(j) == towctrans(j, t));
+ }
+ t = wctrans("elephant");
+ ATF_REQUIRE(t == 0);
+ for (i = 0; i < 65536; i++)
+ ATF_REQUIRE(towctrans(i, t) == i);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, towctrans_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/wcrtomb_test.c b/lib/libc/tests/locale/wcrtomb_test.c
new file mode 100644
index 0000000..09199ba
--- /dev/null
+++ b/lib/libc/tests/locale/wcrtomb_test.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wcrtomb(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(wcrtomb_test);
+ATF_TC_BODY(wcrtomb_test, tc)
+{
+ mbstate_t s;
+ size_t len;
+ char buf[MB_LEN_MAX + 1];
+
+ /* C/POSIX locale. */
+
+ ATF_REQUIRE(MB_CUR_MAX == 1);
+
+ /*
+ * If the buffer argument is NULL, wc is implicitly L'\0',
+ * wcrtomb() resets its internal state.
+ */
+ ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
+ ATF_REQUIRE(wcrtomb(NULL, UCHAR_MAX + 1, NULL) == 1);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ len = wcrtomb(buf, L'\0', &s);
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
+ ATF_REQUIRE(wcrtomb(NULL, L'A', NULL) == 1);
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ len = wcrtomb(buf, L'A', &s);
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
+
+ /* Invalid code. */
+ ATF_REQUIRE(wcrtomb(buf, UCHAR_MAX + 1, NULL) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX == 3);
+
+ /*
+ * If the buffer argument is NULL, wc is implicitly L'\0',
+ * wcrtomb() resets its internal state.
+ */
+ ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
+
+ /* Null wide character. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ len = wcrtomb(buf, L'\0', &s);
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
+
+ /* Latin letter A, internal state. */
+ ATF_REQUIRE(wcrtomb(NULL, L'\0', NULL) == 1);
+ ATF_REQUIRE(wcrtomb(NULL, L'A', NULL) == 1);
+
+ /* Latin letter A. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ len = wcrtomb(buf, L'A', &s);
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
+
+ /* Full width letter A. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ len = wcrtomb(buf, 0xa3c1, &s);
+ ATF_REQUIRE(len == 2);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xa3 &&
+ (unsigned char)buf[1] == 0xc1 &&
+ (unsigned char)buf[2] == 0xcc);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcrtomb_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/wcsnrtombs_test.c b/lib/libc/tests/locale/wcsnrtombs_test.c
new file mode 100644
index 0000000..2e330a1
--- /dev/null
+++ b/lib/libc/tests/locale/wcsnrtombs_test.c
@@ -0,0 +1,195 @@
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wcsnrtombs().
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(wcsnrtombs_test);
+ATF_TC_BODY(wcsnrtombs_test, tc)
+{
+ wchar_t srcbuf[128];
+ char dstbuf[128];
+ wchar_t *src;
+ mbstate_t s;
+
+ /* C/POSIX locale. */
+
+ /* Simple null terminated string. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
+ &s) == 5);
+ ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Simple null terminated string, stopping early. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 4, sizeof(dstbuf),
+ &s) == 4);
+ ATF_REQUIRE(memcmp(dstbuf, "hell", 4) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
+ ATF_REQUIRE(src == srcbuf + 4);
+
+ /* Not enough space in destination buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 4,
+ &s) == 4);
+ ATF_REQUIRE(memcmp(dstbuf, "hell", 4) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
+ ATF_REQUIRE(src == srcbuf + 4);
+
+ /* Null terminated string, internal dest. buffer */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(NULL, (const wchar_t **)&src, 6, sizeof(dstbuf),
+ &s) == 5);
+
+ /* Null terminated string, internal dest. buffer, stopping early. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(NULL, (const wchar_t **)&src, 4, sizeof(dstbuf),
+ &s) == 4);
+
+ /* Null terminated string, internal state. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
+ NULL) == 5);
+ ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Null terminated string, internal state, internal dest. buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ src = srcbuf;
+ ATF_REQUIRE(wcsnrtombs(NULL, (const wchar_t **)&src, 6, 0, NULL) == 5);
+
+ /* Empty source buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ srcbuf[0] = L'\0';
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 1, sizeof(dstbuf),
+ &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == L'\0');
+
+ /* Zero length destination buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 0, &s) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[0] == 0xcc);
+
+ /* Zero length source buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 0, sizeof(dstbuf),
+ &s) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[0] == 0xcc);
+ ATF_REQUIRE(src == srcbuf);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ srcbuf[0] = 0xA3C1;
+ srcbuf[1] = 0x0020;
+ srcbuf[2] = 0x0042;
+ srcbuf[3] = 0x0020;
+ srcbuf[4] = 0xA3C3;
+ srcbuf[5] = 0x0000;
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, sizeof(dstbuf),
+ &s) == 7);
+ ATF_REQUIRE(strcmp(dstbuf, "\xA3\xC1 B \xA3\xC3") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[8] == 0xcc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Stopping early. */
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsnrtombs(dstbuf, (const wchar_t **)&src, 6, 6,
+ &s) == 5);
+ ATF_REQUIRE(memcmp(dstbuf, "\xA3\xC1 B ", 5) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
+ ATF_REQUIRE(src == srcbuf + 4);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcsnrtombs_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/wcsrtombs_test.c b/lib/libc/tests/locale/wcsrtombs_test.c
new file mode 100644
index 0000000..4c3455a8
--- /dev/null
+++ b/lib/libc/tests/locale/wcsrtombs_test.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wcsrtombs(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(wcsrtombs_test);
+ATF_TC_BODY(wcsrtombs_test, tc)
+{
+ wchar_t srcbuf[128];
+ char dstbuf[128];
+ wchar_t *src;
+ mbstate_t s;
+
+ /* C/POSIX locale. */
+
+ /* Simple null terminated string. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsrtombs(dstbuf, (const wchar_t **)&src, sizeof(dstbuf),
+ &s) == 5);
+ ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Not enough space in destination buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsrtombs(dstbuf, (const wchar_t **)&src, 4,
+ &s) == 4);
+ ATF_REQUIRE(memcmp(dstbuf, "hell", 4) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
+ ATF_REQUIRE(src == srcbuf + 4);
+
+ /* Null terminated string, internal dest. buffer */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsrtombs(NULL, (const wchar_t **)&src, sizeof(dstbuf),
+ &s) == 5);
+
+ /* Null terminated string, internal state. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ ATF_REQUIRE(wcsrtombs(dstbuf, (const wchar_t **)&src, sizeof(dstbuf),
+ NULL) == 5);
+ ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
+ ATF_REQUIRE(src == NULL);
+
+ /* Null terminated string, internal state, internal dest. buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ src = srcbuf;
+ ATF_REQUIRE(wcsrtombs(NULL, (const wchar_t **)&src, 0, NULL) == 5);
+
+ /* Empty source buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ srcbuf[0] = L'\0';
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsrtombs(dstbuf, (const wchar_t **)&src, sizeof(dstbuf),
+ &s) == 0);
+ ATF_REQUIRE(dstbuf[0] == L'\0');
+
+ /* Zero length destination buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsrtombs(dstbuf, (const wchar_t **)&src, 0, &s) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[0] == 0xcc);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ srcbuf[0] = 0xA3C1;
+ srcbuf[1] = 0x0020;
+ srcbuf[2] = 0x0042;
+ srcbuf[3] = 0x0020;
+ srcbuf[4] = 0xA3C3;
+ srcbuf[5] = 0x0000;
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ src = srcbuf;
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(wcsrtombs(dstbuf, (const wchar_t **)&src, sizeof(dstbuf),
+ &s) == 7);
+ ATF_REQUIRE(strcmp(dstbuf, "\xA3\xC1 B \xA3\xC3") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[8] == 0xcc);
+ ATF_REQUIRE(src == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcsrtombs_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/wcstombs_test.c b/lib/libc/tests/locale/wcstombs_test.c
new file mode 100644
index 0000000..f3fcd81
--- /dev/null
+++ b/lib/libc/tests/locale/wcstombs_test.c
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 2002 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wcstombs(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(wcstombs_test);
+ATF_TC_BODY(wcstombs_test, tc)
+{
+ wchar_t srcbuf[128];
+ char dstbuf[128];
+
+ /* C/POSIX locale. */
+
+ /* Simple null terminated string. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ ATF_REQUIRE(wcstombs(dstbuf, srcbuf, sizeof(dstbuf)) == 5);
+ ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
+
+ /* Not enough space in destination buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ ATF_REQUIRE(wcstombs(dstbuf, srcbuf, 4) == 4);
+ ATF_REQUIRE(memcmp(dstbuf, "hell", 4) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[5] == 0xcc);
+
+ /* Null terminated string, internal dest. buffer */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ ATF_REQUIRE(wcstombs(NULL, srcbuf, sizeof(dstbuf)) == 5);
+
+ /* Null terminated string, internal state. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ ATF_REQUIRE(wcstombs(dstbuf, srcbuf, sizeof(dstbuf)) == 5);
+ ATF_REQUIRE(strcmp(dstbuf, "hello") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[6] == 0xcc);
+
+ /* Null terminated string, internal state, internal dest. buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ ATF_REQUIRE(wcstombs(NULL, srcbuf, 0) == 5);
+
+ /* Empty source buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ srcbuf[0] = L'\0';
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ ATF_REQUIRE(wcstombs(dstbuf, srcbuf, sizeof(dstbuf)) == 0);
+ ATF_REQUIRE(dstbuf[0] == L'\0');
+
+ /* Zero length destination buffer. */
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ wcscpy(srcbuf, L"hello");
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ ATF_REQUIRE(wcstombs(dstbuf, srcbuf, 0) == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[0] == 0xcc);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX > 1);
+
+ wmemset(srcbuf, 0xcc, sizeof(srcbuf) / sizeof(*srcbuf));
+ srcbuf[0] = 0xA3C1;
+ srcbuf[1] = 0x0020;
+ srcbuf[2] = 0x0042;
+ srcbuf[3] = 0x0020;
+ srcbuf[4] = 0xA3C3;
+ srcbuf[5] = 0x0000;
+ memset(dstbuf, 0xcc, sizeof(dstbuf));
+ ATF_REQUIRE(wcstombs(dstbuf, srcbuf, sizeof(dstbuf)) == 7);
+ ATF_REQUIRE(strcmp(dstbuf, "\xA3\xC1 B \xA3\xC3") == 0);
+ ATF_REQUIRE((unsigned char)dstbuf[8] == 0xcc);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcstombs_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/locale/wctomb_test.c b/lib/libc/tests/locale/wctomb_test.c
new file mode 100644
index 0000000..255cda4
--- /dev/null
+++ b/lib/libc/tests/locale/wctomb_test.c
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Test program for wctomb(), as specified by IEEE Std. 1003.1-2001 and
+ * ISO/IEC 9899:1999.
+ *
+ * The function is tested with both the "C" ("POSIX") LC_CTYPE setting and
+ * "ja_JP.eucJP". Other encodings are not tested.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+ATF_TC_WITHOUT_HEAD(wctomb_test);
+ATF_TC_BODY(wctomb_test, tc)
+{
+ size_t len;
+ char buf[MB_LEN_MAX + 1];
+
+ /* C/POSIX locale. */
+
+ ATF_REQUIRE(MB_CUR_MAX == 1);
+
+ /* No shift states in C locale. */
+ ATF_REQUIRE(wctomb(NULL, L'\0') == 0);
+
+ /* Null wide character. */
+ memset(buf, 0xcc, sizeof(buf));
+ len = wctomb(buf, L'\0');
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
+
+ /* Latin letter A. */
+ memset(buf, 0xcc, sizeof(buf));
+ len = wctomb(buf, L'A');
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
+
+ /* Invalid code. */
+ ATF_REQUIRE(wctomb(buf, UCHAR_MAX + 1) == -1);
+ ATF_REQUIRE(wctomb(NULL, 0) == 0);
+
+ /*
+ * Japanese (EUC) locale.
+ */
+
+ ATF_REQUIRE(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
+ ATF_REQUIRE(MB_CUR_MAX == 3);
+
+ /* No shift states in EUC encoding. */
+ ATF_REQUIRE(wctomb(NULL, L'\0') == 0);
+
+ /* Null wide character. */
+ memset(buf, 0xcc, sizeof(buf));
+ len = wctomb(buf, L'\0');
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 0 && (unsigned char)buf[1] == 0xcc);
+
+ /* Latin letter A. */
+ memset(buf, 0xcc, sizeof(buf));
+ len = wctomb(buf, L'A');
+ ATF_REQUIRE(len == 1);
+ ATF_REQUIRE((unsigned char)buf[0] == 'A' && (unsigned char)buf[1] == 0xcc);
+
+ /* Full width letter A. */
+ memset(buf, 0xcc, sizeof(buf));
+ len = wctomb(buf, 0xa3c1);
+ ATF_REQUIRE(len == 2);
+ ATF_REQUIRE((unsigned char)buf[0] == 0xa3 &&
+ (unsigned char)buf[1] == 0xc1 &&
+ (unsigned char)buf[2] == 0xcc);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wctomb_test);
+
+ return (atf_no_error());
+}
OpenPOWER on IntegriCloud