summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/locale
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/regress/lib/libc/locale
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to '')
-rw-r--r--src/regress/lib/libc/locale/Makefile5
-rw-r--r--src/regress/lib/libc/locale/check_isw/Makefile8
-rw-r--r--src/regress/lib/libc/locale/check_isw/check_isw.c147
-rw-r--r--src/regress/lib/libc/locale/mbrtowc/Makefile5
-rw-r--r--src/regress/lib/libc/locale/mbrtowc/test_mbrtowc.c85
-rw-r--r--src/regress/lib/libc/locale/setlocale/Makefile8
-rw-r--r--src/regress/lib/libc/locale/setlocale/setlocale.c125
-rw-r--r--src/regress/lib/libc/locale/uselocale/Makefile10
-rw-r--r--src/regress/lib/libc/locale/uselocale/uselocale.c481
-rw-r--r--src/regress/lib/libc/locale/wcrtomb/Makefile5
-rw-r--r--src/regress/lib/libc/locale/wcrtomb/test_wcrtomb.c85
11 files changed, 0 insertions, 964 deletions
diff --git a/src/regress/lib/libc/locale/Makefile b/src/regress/lib/libc/locale/Makefile
deleted file mode 100644
index 550f176d4c..0000000000
--- a/src/regress/lib/libc/locale/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1# $OpenBSD: Makefile,v 1.7 2020/01/13 15:35:57 bluhm Exp $
2
3SUBDIR = check_isw mbrtowc setlocale uselocale wcrtomb
4
5.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libc/locale/check_isw/Makefile b/src/regress/lib/libc/locale/check_isw/Makefile
deleted file mode 100644
index cd79d6cb7f..0000000000
--- a/src/regress/lib/libc/locale/check_isw/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2017/07/27 15:08:37 bluhm Exp $
2
3PROG = check_isw
4
5run-regress-${PROG}: ${PROG}
6 ./${PROG} >/dev/null
7
8.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/locale/check_isw/check_isw.c b/src/regress/lib/libc/locale/check_isw/check_isw.c
deleted file mode 100644
index 718f387883..0000000000
--- a/src/regress/lib/libc/locale/check_isw/check_isw.c
+++ /dev/null
@@ -1,147 +0,0 @@
1/* $OpenBSD: check_isw.c,v 1.2 2017/07/27 15:08:37 bluhm Exp $ */
2/*
3 * Copyright (c) 2005 Marc Espie <espie@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* This checks consistency of the isw* functions with the default <ctype>
19 * functions.
20 */
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include <wchar.h>
26#include <wctype.h>
27
28int bad = 0;
29
30void
31check_bool(int v1, int v2, char msg)
32{
33 if (!v1 != !v2) {
34 printf("%c", msg);
35 bad++;
36 }
37}
38
39void
40check_value(int v1, int v2, char msg)
41{
42 if (v1 != v2) {
43 printf("%c", msg);
44 bad++;
45 }
46}
47
48void
49test1()
50{
51 int i;
52
53 for (i = 0; i < 256; i++) {
54 printf(" %02x: ", i);
55 check_bool(isalnum(i), iswalnum(i), '1');
56 check_bool(isalpha(i), iswalpha(i), '2');
57 check_bool(isblank(i), iswblank(i), '3');
58 check_bool(iscntrl(i), iswcntrl(i), '4');
59 check_bool(isdigit(i), iswdigit(i), '5');
60 check_bool(isgraph(i), iswgraph(i), '6');
61 check_bool(islower(i), iswlower(i), '6');
62 check_bool(isprint(i), iswprint(i), '7');
63 check_bool(ispunct(i), iswpunct(i), '8');
64 check_bool(isspace(i), iswspace(i), '9');
65 check_bool(isupper(i), iswupper(i), 'a');
66 check_bool(isxdigit(i), iswxdigit(i), 'b');
67 check_value(tolower(i), towlower(i), 'c');
68 check_value(toupper(i), towupper(i), 'd');
69 if (i % 8 == 7)
70 printf("\n");
71 }
72 printf("\n");
73}
74
75void
76test2()
77{
78 unsigned char *s;
79 unsigned char *buf;
80 int i, j;
81 size_t n;
82 wchar_t c, d;
83 mbstate_t state;
84
85 s = malloc(256);
86 if (!s) {
87 bad++;
88 return;
89 }
90 buf = malloc(MB_CUR_MAX);
91 if (!buf) {
92 bad++;
93 free(s);
94 return;
95 }
96 for (i = 0; i < 256; i++)
97 s[i] = i+1;
98
99 j = 0;
100 mbrtowc(NULL, NULL, 1, &state);
101 printf(" %02x: ", 0);
102
103 while ((n = mbrtowc(&c, s+j, 256-j, &state)) == 1) {
104 printf(" %02x: ", s[j]);
105 check_bool(isalnum(s[j]), iswalnum(c), '1');
106 check_bool(isalpha(s[j]), iswalpha(c), '2');
107 check_bool(isblank(s[j]), iswblank(c), '3');
108 check_bool(iscntrl(s[j]), iswcntrl(c), '4');
109 check_bool(isdigit(s[j]), iswdigit(c), '5');
110 check_bool(isgraph(s[j]), iswgraph(c), '6');
111 check_bool(islower(s[j]), iswlower(c), '6');
112 check_bool(isprint(s[j]), iswprint(c), '7');
113 check_bool(ispunct(s[j]), iswpunct(c), '8');
114 check_bool(isspace(s[j]), iswspace(c), '9');
115 check_bool(isupper(s[j]), iswupper(c), 'a');
116 check_bool(isxdigit(s[j]), iswxdigit(c), 'b');
117 d = towlower(c);
118 if (wctomb(buf, d) == 1) {
119 check_value(tolower(s[j]), buf[0], 'c');
120 } else {
121 bad++;
122 }
123 d = towupper(c);
124 if (wctomb(buf, d) == 1) {
125 check_value(toupper(s[j]), buf[0], 'c');
126 } else {
127 bad++;
128 }
129 if (s[j] % 8 == 7)
130 printf("\n");
131 j++;
132 }
133 if (n != 0 || j != 255) {
134 bad++;
135 }
136 free(s);
137 free(buf);
138}
139
140
141int
142main()
143{
144 test1();
145 test2();
146 return bad !=0;
147}
diff --git a/src/regress/lib/libc/locale/mbrtowc/Makefile b/src/regress/lib/libc/locale/mbrtowc/Makefile
deleted file mode 100644
index 5436383911..0000000000
--- a/src/regress/lib/libc/locale/mbrtowc/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2017/07/27 15:08:37 bluhm Exp $
2
3PROG = test_mbrtowc
4
5.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/locale/mbrtowc/test_mbrtowc.c b/src/regress/lib/libc/locale/mbrtowc/test_mbrtowc.c
deleted file mode 100644
index 7455f68439..0000000000
--- a/src/regress/lib/libc/locale/mbrtowc/test_mbrtowc.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/* $OpenBSD: test_mbrtowc.c,v 1.3 2020/03/09 09:29:10 dlg Exp $ */
2/*
3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <err.h>
20#include <errno.h>
21#include <locale.h>
22#include <stdlib.h>
23#include <string.h>
24#include <wchar.h>
25
26static mbstate_t mbs;
27
28void
29onetest(const char *name, const char *in, size_t insz,
30 int outerr, size_t outsz, wint_t out)
31{
32 wchar_t wc;
33 size_t sz;
34
35 sz = mbrtowc(&wc, in, insz, &mbs);
36 if (errno != outerr)
37 err(1, "%zu %s(%zd)", MB_CUR_MAX, name, insz);
38 if (sz != outsz || (out != WEOF && wc != out))
39 errx(1, "%zu %s(%zd) = (%zd, %d) != (%zd, %d)",
40 MB_CUR_MAX, name, insz, sz, wc, outsz, out);
41 if (mbsinit(&mbs) == (insz && outsz == (size_t)-2))
42 errx(1, "%zu %s(%zd) mbsinit", MB_CUR_MAX, name, insz);
43 if (errno == 0 && outerr == 0)
44 return;
45 errno = 0;
46 memset(&mbs, 0, sizeof(mbs));
47}
48
49int
50main(void)
51{
52 onetest("NUL", "", 0, 0, -2, WEOF);
53 onetest("NUL", "", 2, 0, 0, L'\0');
54 onetest("BEL", "\a", 2, 0, 1, L'\a');
55 onetest("A", "A", 2, 0, 1, L'A');
56 onetest("DEL", "\177", 2, 0, 1, L'\177');
57 onetest("CSI", "\233", 2, 0, 1, L'\233');
58
59 if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL)
60 errx(1, "setlocale(UTF-8) failed");
61
62 onetest("NUL", "", 0, 0, -2, WEOF);
63 onetest("NUL", "", 8, 0, 0, L'\0');
64 onetest("BEL", "\a", 8, 0, 1, L'\a');
65 onetest("A", "A", 8, 0, 1, L'A');
66 onetest("DEL", "\177", 8, 0, 1, L'\177');
67 onetest("0x80", "\200", 8, EILSEQ, -1, WEOF);
68 onetest("0xc3", "\303", 1, 0, -2, WEOF);
69 onetest("U+00E9", "\251", 8, 0, 1, 0xe9);
70 onetest("0xec", "\354", 1, 0, -2, WEOF);
71 onetest("0xecbf", "\277", 1, 0, -2, WEOF);
72 onetest("U+CFFF", "\277", 8, 0, 1, 0xcfff);
73
74 if (setlocale(LC_CTYPE, "POSIX") == NULL)
75 errx(1, "setlocale(POSIX) failed");
76
77 onetest("0xff", "\277", 2, 0, 1, L'\277');
78
79 if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL)
80 errx(1, "second setlocale(UTF-8) failed");
81
82 onetest("U+13000", "\360\223\200\200", 8, 0, 4, 0x13000);
83
84 return 0;
85}
diff --git a/src/regress/lib/libc/locale/setlocale/Makefile b/src/regress/lib/libc/locale/setlocale/Makefile
deleted file mode 100644
index 966f7926e5..0000000000
--- a/src/regress/lib/libc/locale/setlocale/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2017/07/27 15:08:37 bluhm Exp $
2
3PROG = setlocale
4
5run-regress-${PROG}: ${PROG}
6 env -i LC_ALL=fr_FR.UTF-8 ./${PROG}
7
8.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/locale/setlocale/setlocale.c b/src/regress/lib/libc/locale/setlocale/setlocale.c
deleted file mode 100644
index 82245df5c5..0000000000
--- a/src/regress/lib/libc/locale/setlocale/setlocale.c
+++ /dev/null
@@ -1,125 +0,0 @@
1/* $OpenBSD: setlocale.c,v 1.4 2018/03/29 16:34:25 schwarze Exp $ */
2/*
3 * Copyright (c) 2015 Sebastien Marie <semarie@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <err.h>
19#include <locale.h>
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <ctype.h>
24
25/*
26 * test helpers for __LINE__
27 */
28#define test_setlocale(_e, _c, _l) _test_setlocale(_e, _c, _l, __LINE__)
29#define test_MB_CUR_MAX(_e) _test_MB_CUR_MAX(_e, __LINE__)
30#define test_isalpha(_e, _c) _test_isalpha(_e, _c, __LINE__)
31
32
33static void
34_test_setlocale(char *expected, int category, char *locale, int line)
35{
36 char *result = setlocale(category, locale);
37
38 if ((expected == NULL) || (result == NULL)) {
39 if (expected == result)
40 return;
41
42 errx(1, "[%d] setlocale(%d, \"%s\")=\"%s\" [expected: \"%s\"]",
43 line, category, locale, result, expected);
44 }
45
46 if (strcmp(expected, result) != 0)
47 errx(1, "[%d] setlocale(%d, \"%s\")=\"%s\" [expected: \"%s\"]",
48 line, category, locale, result, expected);
49}
50
51static void
52_test_MB_CUR_MAX(size_t expected, int line)
53{
54 if (MB_CUR_MAX != expected)
55 errx(1, "[%d] MB_CUR_MAX=%ld [expected %ld]",
56 line, MB_CUR_MAX, expected);
57}
58
59static void
60_test_isalpha(int expected, int c, int line)
61{
62 int result = isalpha(c);
63 if (!!result != expected)
64 errx(1, "[%d] isalpha(%d)=%d [expected %d]",
65 line, c, result, expected);
66}
67
68int
69main(int argc, char *argv[])
70{
71 /* check initial state (should be "C") */
72 test_setlocale("C", LC_ALL, NULL); /* check */
73 test_MB_CUR_MAX(1);
74 test_isalpha(0, 0xe9); /* iso-8859-1 eacute */
75
76 /* load from env */
77 /* NOTE: we don't support non-C locales for some categories */
78 test_setlocale("fr_FR.UTF-8", LC_CTYPE, ""); /* set */
79 test_setlocale("fr_FR.UTF-8", LC_MESSAGES, ""); /* set */
80 test_MB_CUR_MAX(4);
81 test_isalpha(0, 0xe9); /* iso-8859-1 eacute */
82
83 test_setlocale("C", LC_MESSAGES, "C"); /* set */
84 test_MB_CUR_MAX(4);
85 test_setlocale("C/fr_FR.UTF-8/C/C/C/C", LC_ALL, NULL); /* check */
86
87 test_setlocale("C", LC_CTYPE, "C"); /* set */
88 test_MB_CUR_MAX(1);
89 test_setlocale("C", LC_ALL, NULL); /* check */
90
91 /* check for errors on checking */
92 test_setlocale("C", LC_ALL, "C"); /* reset */
93 test_setlocale(NULL, -1, NULL);
94 test_setlocale(NULL, _LC_LAST, NULL);
95 test_setlocale(NULL, _LC_LAST+0xff, NULL);
96 test_setlocale("C", LC_ALL, NULL); /* check */
97
98 /* check for errors on setting */
99 test_setlocale(NULL, -1, "");
100 test_setlocale(NULL, _LC_LAST, "");
101 test_setlocale(NULL, _LC_LAST+0xff, "");
102 test_setlocale("C", LC_ALL, NULL); /* check */
103
104 /* no codeset, fallback to ASCII */
105 test_setlocale("C", LC_ALL, "C"); /* reset */
106 test_setlocale("invalid", LC_CTYPE, "invalid"); /* set */
107 test_setlocale("invalid", LC_CTYPE, NULL);
108 test_MB_CUR_MAX(1);
109 test_isalpha(0, 0xe9); /* iso-8859-1 eacute */
110
111 /* with codeset */
112 test_setlocale("C", LC_ALL, "C"); /* reset */
113 test_setlocale("invalid.UTF-8", LC_CTYPE, "invalid.UTF-8"); /* set */
114 test_setlocale("invalid.UTF-8", LC_CTYPE, NULL);
115 test_setlocale("C/invalid.UTF-8/C/C/C/C", LC_ALL, NULL);
116 test_MB_CUR_MAX(4);
117
118 /* with invalid codeset (is an error) */
119 test_setlocale("C", LC_ALL, "C"); /* reset */
120 test_setlocale(NULL, LC_CTYPE, "fr_FR.invalid"); /* set */
121 test_setlocale("C", LC_CTYPE, NULL);
122 test_MB_CUR_MAX(1);
123
124 return (EXIT_SUCCESS);
125}
diff --git a/src/regress/lib/libc/locale/uselocale/Makefile b/src/regress/lib/libc/locale/uselocale/Makefile
deleted file mode 100644
index a10471bcf6..0000000000
--- a/src/regress/lib/libc/locale/uselocale/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1# $OpenBSD: Makefile,v 1.3 2017/08/16 01:40:30 schwarze Exp $
2
3PROG = uselocale
4CFLAGS += -Wno-macro-redefined -Wno-int-to-pointer-cast
5LDFLAGS += -pthread
6
7run-regress-${PROG}: ${PROG}
8 ./${PROG}
9
10.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/locale/uselocale/uselocale.c b/src/regress/lib/libc/locale/uselocale/uselocale.c
deleted file mode 100644
index 4759eff46c..0000000000
--- a/src/regress/lib/libc/locale/uselocale/uselocale.c
+++ /dev/null
@@ -1,481 +0,0 @@
1/* $OpenBSD: uselocale.c,v 1.9 2024/02/05 06:48:04 anton Exp $ */
2/*
3 * Copyright (c) 2017, 2022 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <ctype.h>
19#include <err.h>
20#include <errno.h>
21#include <langinfo.h>
22#include <locale.h>
23#include <pthread.h>
24#include <stdlib.h>
25#include <string.h>
26#include <wchar.h>
27#include <wctype.h>
28
29/* Keep in sync with /usr/src/lib/libc/locale/rune.h. */
30#define _LOCALE_NONE (locale_t)0
31#define _LOCALE_C (locale_t)1
32#define _LOCALE_UTF8 (locale_t)2
33#define _LOCALE_BAD (locale_t)3
34
35/* Options for switch_thread() below. */
36#define SWITCH_SIGNAL 1 /* Call pthread_cond_signal(3). */
37#define SWITCH_WAIT 2 /* Call pthread_cond_timedwait(3). */
38
39/* Options for TESTFUNC(). */
40#define TOPT_ERR (1 << 0)
41
42/*
43 * Generate one test function for a specific interface.
44 * Fn = function name
45 * Ft = function return type
46 * FUNCPARA = function parameter list with types and names
47 * FUNCARGS = function argument list, names only, no types
48 * Af = format string to print the arguments
49 * Rf = format string to print the return value
50 * Op = options for the test function, see above
51 * line = source code line number in this test file
52 * ee = expected error number
53 * er = expected return value
54 * ar = actual return value
55 * errno = actual error number (global)
56 */
57#define TESTFUNC(Fn, Ft, Af, Rf, Op) \
58static void \
59_test_##Fn(int line, int ee, Ft er, FUNCPARA) \
60{ \
61 Ft ar; \
62 errno = 0; \
63 ar = Fn(FUNCARGS); \
64 if (ar != er) \
65 errx(1, "[%d] %s(" Af ")=" Rf " [exp: " Rf "]", \
66 line, #Fn, FUNCARGS, ar, er); \
67 if (Op & TOPT_ERR && errno != ee) \
68 errx(1, "[%d] %s(" Af ") errno=%d [exp: %d]", \
69 line, #Fn, FUNCARGS, errno, ee); \
70}
71
72#define STRTESTFUNC(Fn, Af) \
73static void \
74_test_##Fn(int line, int ee, const char *er, FUNCPARA) \
75{ \
76 const char *ar; \
77 errno = 0; \
78 ar = Fn(FUNCARGS); \
79 if (er == NULL) \
80 er = "NULL"; \
81 if (ar == NULL) \
82 ar = "NULL"; \
83 if (strcmp((const char *)er, (const char *)ar) != 0) \
84 errx(1, "[%d] %s(" Af ")=%s [exp: %s]", \
85 line, #Fn, FUNCARGS, ar, er); \
86}
87
88/*
89 * Test functions for all tested interfaces.
90 */
91#define FUNCPARA int mask, const char *locname
92#define FUNCARGS mask, locname, _LOCALE_NONE
93TESTFUNC(newlocale, locale_t, "%d, %s, %p", "%p", TOPT_ERR)
94
95#define FUNCPARA locale_t locale
96#define FUNCARGS locale
97TESTFUNC(duplocale, locale_t, "%p", "%p", TOPT_ERR)
98TESTFUNC(uselocale, locale_t, "%p", "%p", TOPT_ERR)
99
100#define FUNCPARA int category, char *locname
101#define FUNCARGS category, locname
102STRTESTFUNC(setlocale, "%d, %s")
103
104#define FUNCPARA nl_item item
105#define FUNCARGS item
106STRTESTFUNC(nl_langinfo, "%ld")
107
108#define FUNCPARA nl_item item, locale_t locale
109#define FUNCARGS item, locale
110STRTESTFUNC(nl_langinfo_l, "%ld, %p")
111
112#define FUNCPARA int c
113#define FUNCARGS c
114TESTFUNC(isalpha, int, "0x%.2x", "%d", 0)
115TESTFUNC(tolower, int, "0x%.2x", "0x%.2x", 0)
116
117#define FUNCPARA int c, locale_t locale
118#define FUNCARGS c, locale
119TESTFUNC(isalpha_l, int, "0x%.2x, %p", "%d", 0)
120TESTFUNC(tolower_l, int, "0x%.2x, %p", "0x%.2x", 0)
121
122#define FUNCPARA wint_t wc
123#define FUNCARGS wc
124TESTFUNC(iswalpha, int, "U+%.4X", "%d", 0)
125TESTFUNC(towupper, wint_t, "U+%.4X", "U+%.4X", 0)
126
127#define FUNCPARA wint_t wc, locale_t locale
128#define FUNCARGS wc, locale
129TESTFUNC(iswalpha_l, int, "U+%.4X, %p", "%d", 0)
130TESTFUNC(towupper_l, wint_t, "U+%.4X, %p", "U+%.4X", 0)
131
132#define FUNCPARA wint_t wc, wctype_t charclass
133#define FUNCARGS wc, charclass
134TESTFUNC(iswctype, int, "U+%.4X, %p", "%d", 0)
135
136#define FUNCPARA wint_t wc, wctype_t charclass, locale_t locale
137#define FUNCARGS wc, charclass, locale
138TESTFUNC(iswctype_l, int, "U+%.4X, %p, %p", "%d", 0)
139
140#define FUNCPARA wint_t wc, wctrans_t charmap
141#define FUNCARGS wc, charmap
142TESTFUNC(towctrans, wint_t, "U+%.4X, %p", "U+%.4X", 0)
143
144#define FUNCPARA wint_t wc, wctrans_t charmap, locale_t locale
145#define FUNCARGS wc, charmap, locale
146TESTFUNC(towctrans_l, wint_t, "U+%.4X, %p, %p", "U+%.4X", 0)
147
148#define FUNCPARA const wchar_t *s1, const wchar_t *s2
149#define FUNCARGS s1, s2
150TESTFUNC(wcscasecmp, int, "%ls, %ls", "%d", 0)
151
152#define FUNCPARA const wchar_t *s1, const wchar_t *s2, locale_t locale
153#define FUNCARGS s1, s2, locale
154TESTFUNC(wcscasecmp_l, int, "%ls, %ls, %p", "%d", 0)
155
156#define FUNCPARA const wchar_t *s1, const wchar_t *s2, size_t len
157#define FUNCARGS s1, s2, len
158TESTFUNC(wcsncasecmp, int, "%ls, %ls, %zu", "%d", 0)
159
160#define FUNCPARA const wchar_t *s1, const wchar_t *s2, size_t len, \
161 locale_t locale
162#define FUNCARGS s1, s2, len, locale
163TESTFUNC(wcsncasecmp_l, int, "%ls, %ls, %zu, %p", "%d", 0)
164
165static void
166_test_MB_CUR_MAX(int line, int ee, size_t ar)
167{
168 if (MB_CUR_MAX != ar)
169 errx(1, "[%d] MB_CUR_MAX=%zd [exp: %zd]",
170 line, MB_CUR_MAX, ar);
171}
172
173/*
174 * Test macros:
175 * TEST_R(funcname, er, arguments) if you expect errno == 0.
176 * TEST_ER(funcname, ee, er, arguments) otherwise.
177 */
178#define TEST_R(Fn, ...) _test_##Fn(__LINE__, 0, __VA_ARGS__)
179#define TEST_ER(Fn, ...) _test_##Fn(__LINE__, __VA_ARGS__)
180
181static pthread_mutex_t mtx;
182static pthread_mutexattr_t mtxattr;
183static pthread_cond_t cond;
184
185/*
186 * SWITCH_SIGNAL wakes the other thread.
187 * SWITCH_WAIT goes to sleep.
188 * Both can be combined.
189 * The step argument is used for error reporting only.
190 */
191static void
192switch_thread(int step, int flags)
193{
194 struct timespec t;
195 int irc;
196
197 if (flags & SWITCH_SIGNAL) {
198 if ((irc = pthread_cond_signal(&cond)) != 0)
199 errc(1, irc, "pthread_cond_signal(%d)", step);
200 }
201 if (flags & SWITCH_WAIT) {
202 if ((irc = pthread_mutex_trylock(&mtx)) != 0)
203 errc(1, irc, "pthread_mutex_trylock(%d)", step);
204 t.tv_sec = time(NULL) + 2;
205 t.tv_nsec = 0;
206 if ((irc = pthread_cond_timedwait(&cond, &mtx, &t)) != 0)
207 errc(1, irc, "pthread_cond_timedwait(%d)", step);
208 if ((irc = pthread_mutex_unlock(&mtx)) != 0)
209 errc(1, irc, "pthread_mutex_unlock(%d)", step);
210 }
211}
212
213static void *
214child_func(void *arg)
215{
216 const wchar_t s1[] = { 0x00C7, 0x00E0, 0x0000 };
217 const wchar_t s2[] = { 0x00E7, 0x00C0, 0x0000 };
218 const wchar_t s3[] = { 0x00C9, 0x0074, 0x00C9, 0x0000 };
219 const wchar_t s4[] = { 0x00E9, 0x0054, 0x00CC, 0x0000 };
220 wctype_t wctyg, wctyu, wctyc;
221 wctrans_t wctrg, wctru, wctrc;
222 char *sego, *segc, *selo, *selc;
223
224 /* Test invalid newlocale(3) arguments. */
225 TEST_ER(newlocale, EINVAL, _LOCALE_NONE, LC_CTYPE_MASK, NULL);
226 TEST_R(MB_CUR_MAX, 1);
227 TEST_ER(newlocale, EINVAL, _LOCALE_NONE, LC_ALL_MASK + 1, "C.UTF-8");
228 TEST_R(MB_CUR_MAX, 1);
229 TEST_ER(newlocale, ENOENT, _LOCALE_NONE, LC_COLLATE_MASK, "C.INV");
230 TEST_R(MB_CUR_MAX, 1);
231 setenv("LC_TIME", "C.INV", 1);
232 TEST_ER(newlocale, ENOENT, _LOCALE_NONE, LC_TIME_MASK, "");
233 unsetenv("LC_TIME");
234 TEST_R(MB_CUR_MAX, 1);
235 setenv("LC_CTYPE", "C.INV", 1);
236 TEST_ER(newlocale, ENOENT, _LOCALE_NONE, LC_CTYPE_MASK, "");
237 TEST_R(MB_CUR_MAX, 1);
238
239 /* Test duplocale(3). */
240 TEST_ER(duplocale, EINVAL, _LOCALE_NONE, _LOCALE_UTF8);
241 TEST_R(duplocale, _LOCALE_C, _LOCALE_C);
242 TEST_R(duplocale, _LOCALE_C, LC_GLOBAL_LOCALE);
243
244 /* Test premature UTF-8 uselocale(3). */
245 TEST_ER(uselocale, EINVAL, _LOCALE_NONE, _LOCALE_UTF8);
246 TEST_R(MB_CUR_MAX, 1);
247 TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE);
248
249 /* Test UTF-8 initialization. */
250 setenv("LC_CTYPE", "C.UTF-8", 1);
251 TEST_R(newlocale, _LOCALE_UTF8, LC_CTYPE_MASK, "");
252 unsetenv("LC_CTYPE");
253 TEST_R(MB_CUR_MAX, 1);
254 TEST_R(duplocale, _LOCALE_UTF8, _LOCALE_UTF8);
255
256 /* Test invalid uselocale(3) argument. */
257 TEST_ER(uselocale, EINVAL, _LOCALE_NONE, _LOCALE_BAD);
258 TEST_R(MB_CUR_MAX, 1);
259 TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE);
260 TEST_R(nl_langinfo, "US-ASCII", CODESET);
261 TEST_R(nl_langinfo_l, "UTF-8", CODESET, _LOCALE_UTF8);
262 TEST_R(iswalpha, 0, 0x00E9);
263 TEST_R(iswalpha_l, 1, 0x00E9, _LOCALE_UTF8);
264 TEST_R(towupper, 0x00E9, 0x00E9);
265 TEST_R(towupper_l, 0x00C9, 0x00E9, _LOCALE_UTF8);
266 TEST_R(wcscasecmp, *s1 - *s2, s1, s2);
267 TEST_R(wcscasecmp_l, 0, s1, s2, _LOCALE_UTF8);
268
269 /* Test switching the thread locale. */
270 TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_UTF8);
271 TEST_R(MB_CUR_MAX, 4);
272 TEST_R(uselocale, _LOCALE_UTF8, _LOCALE_NONE);
273 TEST_R(nl_langinfo, "UTF-8", CODESET);
274 TEST_R(nl_langinfo_l, "UTF-8", CODESET, _LOCALE_UTF8);
275 TEST_R(nl_langinfo_l, "US-ASCII", CODESET, _LOCALE_C);
276 TEST_R(isalpha, _CTYPE_L, 0x65); /* e */
277 TEST_R(isalpha_l, _CTYPE_L, 0x65, _LOCALE_UTF8);
278 TEST_R(isalpha_l, _CTYPE_L, 0x65, _LOCALE_C);
279 TEST_R(isalpha_l, _CTYPE_L, 0x65, _LOCALE_C);
280 TEST_R(isalpha, 0, 0x30); /* 0 */
281 TEST_R(isalpha_l, 0, 0x30, _LOCALE_UTF8);
282 TEST_R(isalpha_l, 0, 0x30, _LOCALE_C);
283 TEST_R(tolower, 0x61, 0x41); /* A */
284 TEST_R(tolower_l, 0x61, 0x41, _LOCALE_UTF8);
285 TEST_R(tolower_l, 0x61, 0x41, _LOCALE_C);
286 TEST_R(tolower, 0x40, 0x40); /* @ */
287 TEST_R(tolower_l, 0x40, 0x40, _LOCALE_UTF8);
288 TEST_R(tolower_l, 0x40, 0x40, _LOCALE_C);
289 TEST_R(iswalpha, 1, 0x00E9); /* e accent aigu */
290 TEST_R(iswalpha_l, 1, 0x00E9, _LOCALE_UTF8);
291 TEST_R(iswalpha_l, 0, 0x00E9, _LOCALE_C);
292 TEST_R(iswalpha, 1, 0x0153); /* ligature oe */
293 TEST_R(iswalpha_l, 1, 0x0153, _LOCALE_UTF8);
294 TEST_R(iswalpha_l, 0, 0x0153, _LOCALE_C);
295 TEST_R(iswalpha, 0, 0x2200); /* for all */
296 TEST_R(iswalpha_l, 0, 0x2200, _LOCALE_UTF8);
297 TEST_R(iswalpha_l, 0, 0x2200, _LOCALE_C);
298 TEST_R(towupper, 0x00C9, 0x00E9);
299 TEST_R(towupper_l, 0x00C9, 0x00E9, _LOCALE_UTF8);
300 TEST_R(towupper_l, 0x00E9, 0x00E9, _LOCALE_C);
301 TEST_R(towupper, 0x0152, 0x0153);
302 TEST_R(towupper_l, 0x0152, 0x0153, _LOCALE_UTF8);
303 TEST_R(towupper_l, 0x0153, 0x0153, _LOCALE_C);
304 TEST_R(towupper, 0x2205, 0x2205);
305 TEST_R(towupper_l, 0x2205, 0x2205, _LOCALE_UTF8);
306 TEST_R(towupper_l, 0x2205, 0x2205, _LOCALE_C);
307 wctyg = wctype("upper");
308 if (wctyg == NULL)
309 errx(1, "wctype(upper) == NULL");
310 wctyu = wctype_l("upper", _LOCALE_UTF8);
311 if (wctyu == NULL)
312 errx(1, "wctype_l(upper, UTF-8) == NULL");
313 if (wctyg != wctyu)
314 errx(1, "wctype global != UTF-8");
315 wctyc = wctype_l("upper", _LOCALE_C);
316 if (wctyc == NULL)
317 errx(1, "wctype_l(upper, C) == NULL");
318 TEST_R(iswctype, 1, 0x00D0, wctyg); /* Eth */
319 TEST_R(iswctype_l, 1, 0x00D0, wctyu, _LOCALE_UTF8);
320 TEST_R(iswctype_l, 0, 0x00D0, wctyc, _LOCALE_C);
321 TEST_R(iswctype, 1, 0x0393, wctyg); /* Gamma */
322 TEST_R(iswctype_l, 1, 0x0393, wctyu, _LOCALE_UTF8);
323 TEST_R(iswctype_l, 0, 0x0393, wctyc, _LOCALE_C);
324 TEST_R(iswctype, 0, 0x2205, wctyg); /* empty set */
325 TEST_R(iswctype_l, 0, 0x2205, wctyu, _LOCALE_UTF8);
326 TEST_R(iswctype_l, 0, 0x2205, wctyc, _LOCALE_C);
327 wctrg = wctrans("tolower");
328 if (wctrg == NULL)
329 errx(1, "wctrans(tolower) == NULL");
330 wctru = wctrans_l("tolower", _LOCALE_UTF8);
331 if (wctru == NULL)
332 errx(1, "wctrans(tolower, UTF-8) == NULL");
333 if (wctrg != wctru)
334 errx(1, "wctrans global != UTF-8");
335 wctrc = wctrans_l("tolower", _LOCALE_C);
336 if (wctrc == NULL)
337 errx(1, "wctrans(tolower, C) == NULL");
338 TEST_R(towctrans, 0x00FE, 0x00DE, wctrg); /* Thorn */
339 TEST_R(towctrans_l, 0x00FE, 0x00DE, wctru, _LOCALE_UTF8);
340 TEST_R(towctrans_l, 0x00DE, 0x00DE, wctrc, _LOCALE_C);
341 TEST_R(towctrans, 0x03C6, 0x03A6, wctrg); /* Phi */
342 TEST_R(towctrans_l, 0x03C6, 0x03A6, wctru, _LOCALE_UTF8);
343 TEST_R(towctrans_l, 0x03A6, 0x03A6, wctrc, _LOCALE_C);
344 TEST_R(towctrans, 0x2207, 0x2207, wctrg); /* Nabla */
345 TEST_R(towctrans_l, 0x2207, 0x2207, wctru, _LOCALE_UTF8);
346 TEST_R(towctrans_l, 0x2207, 0x2207, wctrc, _LOCALE_C);
347 TEST_R(wcscasecmp, 0, s1, s2);
348 TEST_R(wcscasecmp_l, 0, s1, s2, _LOCALE_UTF8);
349 TEST_R(wcscasecmp_l, *s1 - *s2, s1, s2, _LOCALE_C);
350 TEST_R(wcsncasecmp, 0, s3, s4, 2);
351 TEST_R(wcsncasecmp_l, 0, s3, s4, 2, _LOCALE_UTF8);
352 TEST_R(wcsncasecmp_l, *s3 - *s4, s3, s4, 2, _LOCALE_C);
353
354 /* Test non-ctype newlocale(3). */
355 TEST_R(newlocale, _LOCALE_C, LC_MESSAGES_MASK, "en_US.UTF-8");
356
357 /* Test strerror(3). */
358 sego = strerror(EPERM);
359 segc = strdup(sego);
360 selo = strerror_l(ENOENT, _LOCALE_C);
361 selc = strdup(selo);
362 if (strcmp(sego, segc) != 0)
363 errx(1, "child: strerror_l clobbered strerror");
364 free(segc);
365 sego = strerror(ESRCH);
366 if (strcmp(selo, selc) != 0)
367 errx(1, "child: strerror clobbered strerror_l");
368
369 /* Temporarily switch to the main thread. */
370 switch_thread(2, SWITCH_SIGNAL | SWITCH_WAIT);
371 if (strcmp(selo, selc) != 0)
372 errx(1, "child: main clobbered strerror_l");
373 free(selc);
374
375 /* Check that the C locale works even while all is set to UTF-8. */
376 TEST_R(nl_langinfo_l, "US-ASCII", CODESET, _LOCALE_C);
377 TEST_R(iswalpha_l, 0, 0x00E9, _LOCALE_C);
378 TEST_R(towupper_l, 0x00E9, 0x00E9, _LOCALE_C);
379 TEST_R(wcscasecmp_l, *s1 - *s2, s1, s2, _LOCALE_C);
380
381 /* Test displaying the global locale while a local one is set. */
382 TEST_R(setlocale, "C/C.UTF-8/C/C/C/C", LC_ALL, NULL);
383
384 /* Test switching the thread locale back. */
385 TEST_R(MB_CUR_MAX, 4);
386 TEST_R(duplocale, _LOCALE_UTF8, LC_GLOBAL_LOCALE);
387 TEST_R(uselocale, _LOCALE_UTF8, _LOCALE_C);
388 TEST_R(MB_CUR_MAX, 1);
389 TEST_R(uselocale, _LOCALE_C, _LOCALE_NONE);
390
391 /* Check that UTF-8 works even with a C thread locale. */
392 TEST_R(nl_langinfo, "US-ASCII", CODESET);
393 TEST_R(nl_langinfo_l, "UTF-8", CODESET, _LOCALE_UTF8);
394 TEST_R(iswalpha, 0, 0x0153);
395 TEST_R(iswalpha_l, 1, 0x0153, _LOCALE_UTF8);
396 TEST_R(towupper, 0x0153, 0x0153);
397 TEST_R(towupper_l, 0x0152, 0x0153, _LOCALE_UTF8);
398 TEST_R(wcsncasecmp, *s3 - *s4, s3, s4, 2);
399 TEST_R(wcsncasecmp_l, 0, s3, s4, 2, _LOCALE_UTF8);
400
401 /* Test switching back to the global locale. */
402 TEST_R(uselocale, _LOCALE_C, LC_GLOBAL_LOCALE);
403 TEST_R(MB_CUR_MAX, 4);
404 TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE);
405
406 /* Check that the global locale takes effect even in a thread. */
407 TEST_R(nl_langinfo, "UTF-8", CODESET);
408 TEST_R(iswalpha, 1, 0x0153);
409 TEST_R(towupper, 0x0152, 0x0153);
410 TEST_R(wcscasecmp, 0, s1, s2);
411
412 /* Hand control back to the main thread. */
413 switch_thread(4, SWITCH_SIGNAL);
414 return NULL;
415}
416
417int
418main(void)
419{
420 pthread_t child_thread;
421 char *sego, *segc, *selo, *selc;
422 int irc;
423
424 /* Initialize environment. */
425 unsetenv("LC_ALL");
426 unsetenv("LC_COLLATE");
427 unsetenv("LC_CTYPE");
428 unsetenv("LC_MONETARY");
429 unsetenv("LC_NUMERIC");
430 unsetenv("LC_TIME");
431 unsetenv("LC_MESSAGES");
432 unsetenv("LANG");
433
434 if ((irc = pthread_mutexattr_init(&mtxattr)) != 0)
435 errc(1, irc, "pthread_mutexattr_init");
436 if ((irc = pthread_mutexattr_settype(&mtxattr,
437 PTHREAD_MUTEX_STRICT_NP)) != 0)
438 errc(1, irc, "pthread_mutexattr_settype");
439 if ((irc = pthread_mutex_init(&mtx, &mtxattr)) != 0)
440 errc(1, irc, "pthread_mutex_init");
441 if ((irc = pthread_cond_init(&cond, NULL)) != 0)
442 errc(1, irc, "pthread_cond_init");
443
444 /* First let the child do some tests. */
445 if ((irc = pthread_create(&child_thread, NULL, child_func, NULL)) != 0)
446 errc(1, irc, "pthread_create");
447 switch_thread(1, SWITCH_WAIT);
448
449 /* Check that the global locale is undisturbed. */
450 TEST_R(setlocale, "C", LC_ALL, NULL);
451 TEST_R(MB_CUR_MAX, 1);
452
453 /* Check that *_l(3) works without any locale installed. */
454 TEST_R(nl_langinfo_l, "UTF-8", CODESET, _LOCALE_UTF8);
455 TEST_R(iswalpha_l, 1, 0x00E9, _LOCALE_UTF8);
456 TEST_R(towupper_l, 0x00C9, 0x00E9, _LOCALE_UTF8);
457
458 /* Test setting the globale locale. */
459 TEST_R(setlocale, "C.UTF-8", LC_CTYPE, "C.UTF-8");
460 TEST_R(MB_CUR_MAX, 4);
461 TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE);
462
463 /* Test strerror(3). */
464 sego = strerror(EINTR);
465 segc = strdup(sego);
466 selo = strerror_l(EIO, _LOCALE_C);
467 selc = strdup(selo);
468 if (strcmp(sego, segc) != 0)
469 errx(1, "main: strerror_l clobbered strerror");
470 free(segc);
471 sego = strerror(ENXIO);
472 if (strcmp(selo, selc) != 0)
473 errx(1, "main: strerror clobbered strerror_l");
474 free(selc);
475
476 /* Let the child do some more tests, then clean up. */
477 switch_thread(3, SWITCH_SIGNAL);
478 if ((irc = pthread_join(child_thread, NULL)) != 0)
479 errc(1, irc, "pthread_join");
480 return 0;
481}
diff --git a/src/regress/lib/libc/locale/wcrtomb/Makefile b/src/regress/lib/libc/locale/wcrtomb/Makefile
deleted file mode 100644
index b09cecc454..0000000000
--- a/src/regress/lib/libc/locale/wcrtomb/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2017/07/27 15:08:37 bluhm Exp $
2
3PROG = test_wcrtomb
4
5.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/locale/wcrtomb/test_wcrtomb.c b/src/regress/lib/libc/locale/wcrtomb/test_wcrtomb.c
deleted file mode 100644
index ee0e14b69d..0000000000
--- a/src/regress/lib/libc/locale/wcrtomb/test_wcrtomb.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/* $OpenBSD: test_wcrtomb.c,v 1.3 2021/07/03 12:04:53 schwarze Exp $ */
2/*
3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <err.h>
20#include <errno.h>
21#include <limits.h>
22#include <locale.h>
23#include <stdlib.h>
24#include <string.h>
25#include <wchar.h>
26
27static mbstate_t mbs;
28
29void
30onetest(const char *name, const wchar_t wcin, int outerr, const char *out)
31{
32 char buf[MB_LEN_MAX];
33 size_t sz, outsz;
34
35 memset(buf, 0, MB_LEN_MAX);
36 outsz = out == NULL ? (size_t)-1 : *out == '\0' ? 1 : strlen(out);
37 sz = wcrtomb(buf, wcin, &mbs);
38 if (errno != outerr)
39 err(1, "%zu %s U+%04X", MB_CUR_MAX, name, wcin);
40 if (sz != outsz || (out != NULL && strncmp(buf, out, sz)))
41 errx(1, "%zu %s U+%04X: %4.4s(%zd) != %4.4s(%zd)",
42 MB_CUR_MAX, name, wcin, buf, sz,
43 out == NULL ? "(NULL)" : out, outsz);
44 if (mbsinit(&mbs) == 0)
45 errx(1, "%zu %s U+%04X mbsinit", MB_CUR_MAX, name, wcin);
46 if (errno == 0 && outerr == 0)
47 return;
48 errno = 0;
49 memset(&mbs, 0, sizeof(mbs));
50}
51
52int
53main(void)
54{
55 onetest("NUL", L'\0', 0, "");
56 onetest("BEL", L'\a', 0, "\a");
57 onetest("A", L'A', 0, "A");
58 onetest("DEL", L'\177', 0, "\177");
59 onetest("CSI", L'\233', 0, "\233");
60 onetest("0x100", 0x100, EILSEQ, NULL);
61
62 if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL)
63 errx(1, "setlocale(UTF-8) failed");
64
65 onetest("NUL", L'\0', 0, "");
66 onetest("BEL", L'\a', 0, "\a");
67 onetest("A", L'A', 0, "A");
68 onetest("DEL", L'\177', 0, "\177");
69 onetest("CSI", L'\233', 0, "\302\233");
70 onetest("0xe9", 0xe9, 0, "\303\251");
71 onetest("0xcfff", 0xcfff, 0, "\354\277\277");
72 onetest("0xd800", 0xd800, EILSEQ, NULL);
73
74 if (setlocale(LC_CTYPE, "POSIX") == NULL)
75 errx(1, "setlocale(POSIX) failed");
76
77 onetest("0xff", L'\377', 0, "\377");
78
79 if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL)
80 errx(1, "second setlocale(UTF-8) failed");
81
82 onetest("U+13000", 0x13000, 0, "\360\223\200\200");
83
84 return 0;
85}