diff options
author | schwarze <> | 2017-08-16 13:23:56 +0000 |
---|---|---|
committer | schwarze <> | 2017-08-16 13:23:56 +0000 |
commit | 8bf15135a897799a127240c1e77649647d08d890 (patch) | |
tree | d307e0aa6598e9eed20e0c1ee0d24dd2cccb394c | |
parent | 60d2a4f81a2187a90209c4c1cbf0a85eb5c1a5c3 (diff) | |
download | openbsd-8bf15135a897799a127240c1e77649647d08d890.tar.gz openbsd-8bf15135a897799a127240c1e77649647d08d890.tar.bz2 openbsd-8bf15135a897799a127240c1e77649647d08d890.zip |
test isalpha_l(3), tolower_l(3), wctype_l(3), iswctype_l(3),
wctrans_l(3), towctrans_l(3), wcscasecmp_l(3), wcsncasecmp_l(3),
and strerror_l(3)
-rw-r--r-- | src/regress/lib/libc/locale/uselocale/uselocale.c | 153 |
1 files changed, 149 insertions, 4 deletions
diff --git a/src/regress/lib/libc/locale/uselocale/uselocale.c b/src/regress/lib/libc/locale/uselocale/uselocale.c index 01f7bcaca9..1688f07257 100644 --- a/src/regress/lib/libc/locale/uselocale/uselocale.c +++ b/src/regress/lib/libc/locale/uselocale/uselocale.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: uselocale.c,v 1.3 2017/08/16 01:40:30 schwarze Exp $ */ | 1 | /* $OpenBSD: uselocale.c,v 1.4 2017/08/16 13:23:56 schwarze Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> | 3 | * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> |
4 | * | 4 | * |
@@ -15,6 +15,7 @@ | |||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <ctype.h> | ||
18 | #include <err.h> | 19 | #include <err.h> |
19 | #include <errno.h> | 20 | #include <errno.h> |
20 | #include <langinfo.h> | 21 | #include <langinfo.h> |
@@ -22,6 +23,7 @@ | |||
22 | #include <pthread.h> | 23 | #include <pthread.h> |
23 | #include <stdlib.h> | 24 | #include <stdlib.h> |
24 | #include <string.h> | 25 | #include <string.h> |
26 | #include <wchar.h> | ||
25 | #include <wctype.h> | 27 | #include <wctype.h> |
26 | 28 | ||
27 | /* Keep in sync with /usr/src/lib/libc/locale/rune.h. */ | 29 | /* Keep in sync with /usr/src/lib/libc/locale/rune.h. */ |
@@ -99,6 +101,16 @@ TESTFUNC(nl_langinfo, const char *, "%ld", "%s", TOPT_STR) | |||
99 | #define FUNCARGS item, locale | 101 | #define FUNCARGS item, locale |
100 | TESTFUNC(nl_langinfo_l, const char *, "%ld, %p", "%s", TOPT_STR) | 102 | TESTFUNC(nl_langinfo_l, const char *, "%ld, %p", "%s", TOPT_STR) |
101 | 103 | ||
104 | #define FUNCPARA int c | ||
105 | #define FUNCARGS c | ||
106 | TESTFUNC(isalpha, int, "0x%.2x", "%d", 0) | ||
107 | TESTFUNC(tolower, int, "0x%.2x", "0x%.2x", 0) | ||
108 | |||
109 | #define FUNCPARA int c, locale_t locale | ||
110 | #define FUNCARGS c, locale | ||
111 | TESTFUNC(isalpha_l, int, "0x%.2x, %p", "%d", 0) | ||
112 | TESTFUNC(tolower_l, int, "0x%.2x, %p", "0x%.2x", 0) | ||
113 | |||
102 | #define FUNCPARA wint_t wc | 114 | #define FUNCPARA wint_t wc |
103 | #define FUNCARGS wc | 115 | #define FUNCARGS wc |
104 | TESTFUNC(iswalpha, int, "U+%.4X", "%d", 0) | 116 | TESTFUNC(iswalpha, int, "U+%.4X", "%d", 0) |
@@ -109,6 +121,39 @@ TESTFUNC(towupper, wint_t, "U+%.4X", "U+%.4X", 0) | |||
109 | TESTFUNC(iswalpha_l, int, "U+%.4X, %p", "%d", 0) | 121 | TESTFUNC(iswalpha_l, int, "U+%.4X, %p", "%d", 0) |
110 | TESTFUNC(towupper_l, wint_t, "U+%.4X, %p", "U+%.4X", 0) | 122 | TESTFUNC(towupper_l, wint_t, "U+%.4X, %p", "U+%.4X", 0) |
111 | 123 | ||
124 | #define FUNCPARA wint_t wc, wctype_t charclass | ||
125 | #define FUNCARGS wc, charclass | ||
126 | TESTFUNC(iswctype, int, "U+%.4X, %p", "%d", 0) | ||
127 | |||
128 | #define FUNCPARA wint_t wc, wctype_t charclass, locale_t locale | ||
129 | #define FUNCARGS wc, charclass, locale | ||
130 | TESTFUNC(iswctype_l, int, "U+%.4X, %p, %p", "%d", 0) | ||
131 | |||
132 | #define FUNCPARA wint_t wc, wctrans_t charmap | ||
133 | #define FUNCARGS wc, charmap | ||
134 | TESTFUNC(towctrans, wint_t, "U+%.4X, %p", "U+%.4X", 0) | ||
135 | |||
136 | #define FUNCPARA wint_t wc, wctrans_t charmap, locale_t locale | ||
137 | #define FUNCARGS wc, charmap, locale | ||
138 | TESTFUNC(towctrans_l, wint_t, "U+%.4X, %p, %p", "U+%.4X", 0) | ||
139 | |||
140 | #define FUNCPARA const wchar_t *s1, const wchar_t *s2 | ||
141 | #define FUNCARGS s1, s2 | ||
142 | TESTFUNC(wcscasecmp, int, "%ls, %ls", "%d", 0) | ||
143 | |||
144 | #define FUNCPARA const wchar_t *s1, const wchar_t *s2, locale_t locale | ||
145 | #define FUNCARGS s1, s2, locale | ||
146 | TESTFUNC(wcscasecmp_l, int, "%ls, %ls, %p", "%d", 0) | ||
147 | |||
148 | #define FUNCPARA const wchar_t *s1, const wchar_t *s2, size_t len | ||
149 | #define FUNCARGS s1, s2, len | ||
150 | TESTFUNC(wcsncasecmp, int, "%ls, %ls, %zu", "%d", 0) | ||
151 | |||
152 | #define FUNCPARA const wchar_t *s1, const wchar_t *s2, size_t len, \ | ||
153 | locale_t locale | ||
154 | #define FUNCARGS s1, s2, len, locale | ||
155 | TESTFUNC(wcsncasecmp_l, int, "%ls, %ls, %zu, %p", "%d", 0) | ||
156 | |||
112 | static void | 157 | static void |
113 | _test_MB_CUR_MAX(int line, int ee, size_t ar) | 158 | _test_MB_CUR_MAX(int line, int ee, size_t ar) |
114 | { | 159 | { |
@@ -175,6 +220,14 @@ switch_thread(int step, int flags) | |||
175 | static void * | 220 | static void * |
176 | child_func(void *arg) | 221 | child_func(void *arg) |
177 | { | 222 | { |
223 | const wchar_t s1[] = { 0x00C7, 0x00E0, 0x0000 }; | ||
224 | const wchar_t s2[] = { 0x00E7, 0x00C0, 0x0000 }; | ||
225 | const wchar_t s3[] = { 0x00C9, 0x0074, 0x00C9, 0x0000 }; | ||
226 | const wchar_t s4[] = { 0x00E9, 0x0054, 0x00CC, 0x0000 }; | ||
227 | wctype_t wctyg, wctyu, wctyc; | ||
228 | wctrans_t wctrg, wctru, wctrc; | ||
229 | char *sego, *segc, *selo, *selc; | ||
230 | |||
178 | /* Test invalid newlocale(3) arguments. */ | 231 | /* Test invalid newlocale(3) arguments. */ |
179 | TEST_ER(newlocale, EINVAL, _LOCALE_NONE, LC_CTYPE_MASK, NULL); | 232 | TEST_ER(newlocale, EINVAL, _LOCALE_NONE, LC_CTYPE_MASK, NULL); |
180 | TEST_R(MB_CUR_MAX, 1); | 233 | TEST_R(MB_CUR_MAX, 1); |
@@ -219,15 +272,28 @@ child_func(void *arg) | |||
219 | TEST_R(nl_langinfo, "UTF-8", CODESET); | 272 | TEST_R(nl_langinfo, "UTF-8", CODESET); |
220 | TEST_R(nl_langinfo_l, "UTF-8", CODESET, _LOCALE_UTF8); | 273 | TEST_R(nl_langinfo_l, "UTF-8", CODESET, _LOCALE_UTF8); |
221 | TEST_R(nl_langinfo_l, "US-ASCII", CODESET, _LOCALE_C); | 274 | TEST_R(nl_langinfo_l, "US-ASCII", CODESET, _LOCALE_C); |
275 | TEST_R(isalpha, _L, 0x65); /* e */ | ||
276 | TEST_R(isalpha_l, _L, 0x65, _LOCALE_UTF8); | ||
277 | TEST_R(isalpha_l, _L, 0x65, _LOCALE_C); | ||
278 | TEST_R(isalpha_l, _L, 0x65, _LOCALE_C); | ||
279 | TEST_R(isalpha, 0, 0x30); /* 0 */ | ||
280 | TEST_R(isalpha_l, 0, 0x30, _LOCALE_UTF8); | ||
281 | TEST_R(isalpha_l, 0, 0x30, _LOCALE_C); | ||
282 | TEST_R(tolower, 0x61, 0x41); /* A */ | ||
283 | TEST_R(tolower_l, 0x61, 0x41, _LOCALE_UTF8); | ||
284 | TEST_R(tolower_l, 0x61, 0x41, _LOCALE_C); | ||
285 | TEST_R(tolower, 0x40, 0x40); /* @ */ | ||
286 | TEST_R(tolower_l, 0x40, 0x40, _LOCALE_UTF8); | ||
287 | TEST_R(tolower_l, 0x40, 0x40, _LOCALE_C); | ||
222 | TEST_R(iswalpha, 1, 0x00E9); /* e accent aigu */ | 288 | TEST_R(iswalpha, 1, 0x00E9); /* e accent aigu */ |
223 | TEST_R(iswalpha_l, 1, 0x00E9, _LOCALE_UTF8); | 289 | TEST_R(iswalpha_l, 1, 0x00E9, _LOCALE_UTF8); |
224 | TEST_R(iswalpha_l, 0, 0x00E9, _LOCALE_C); | 290 | TEST_R(iswalpha_l, 0, 0x00E9, _LOCALE_C); |
225 | TEST_R(iswalpha, 1, 0x0153); /* ligature oe */ | 291 | TEST_R(iswalpha, 1, 0x0153); /* ligature oe */ |
226 | TEST_R(iswalpha_l, 1, 0x0153, _LOCALE_UTF8); | 292 | TEST_R(iswalpha_l, 1, 0x0153, _LOCALE_UTF8); |
227 | TEST_R(iswalpha_l, 0, 0x0153, _LOCALE_C); | 293 | TEST_R(iswalpha_l, 0, 0x0153, _LOCALE_C); |
228 | TEST_R(iswalpha, 0, 0x2205); /* for all */ | 294 | TEST_R(iswalpha, 0, 0x2200); /* for all */ |
229 | TEST_R(iswalpha_l, 0, 0x2205, _LOCALE_UTF8); | 295 | TEST_R(iswalpha_l, 0, 0x2200, _LOCALE_UTF8); |
230 | TEST_R(iswalpha_l, 0, 0x2205, _LOCALE_C); | 296 | TEST_R(iswalpha_l, 0, 0x2200, _LOCALE_C); |
231 | TEST_R(towupper, 0x00C9, 0x00E9); | 297 | TEST_R(towupper, 0x00C9, 0x00E9); |
232 | TEST_R(towupper_l, 0x00C9, 0x00E9, _LOCALE_UTF8); | 298 | TEST_R(towupper_l, 0x00C9, 0x00E9, _LOCALE_UTF8); |
233 | TEST_R(towupper_l, 0x00E9, 0x00E9, _LOCALE_C); | 299 | TEST_R(towupper_l, 0x00E9, 0x00E9, _LOCALE_C); |
@@ -237,12 +303,77 @@ child_func(void *arg) | |||
237 | TEST_R(towupper, 0x2205, 0x2205); | 303 | TEST_R(towupper, 0x2205, 0x2205); |
238 | TEST_R(towupper_l, 0x2205, 0x2205, _LOCALE_UTF8); | 304 | TEST_R(towupper_l, 0x2205, 0x2205, _LOCALE_UTF8); |
239 | TEST_R(towupper_l, 0x2205, 0x2205, _LOCALE_C); | 305 | TEST_R(towupper_l, 0x2205, 0x2205, _LOCALE_C); |
306 | wctyg = wctype("upper"); | ||
307 | if (wctyg == NULL) | ||
308 | errx(1, "wctype(upper) == NULL"); | ||
309 | wctyu = wctype_l("upper", _LOCALE_UTF8); | ||
310 | if (wctyu == NULL) | ||
311 | errx(1, "wctype_l(upper, UTF-8) == NULL"); | ||
312 | if (wctyg != wctyu) | ||
313 | errx(1, "wctype global != UTF-8"); | ||
314 | wctyc = wctype_l("upper", _LOCALE_C); | ||
315 | if (wctyc == NULL) | ||
316 | errx(1, "wctype_l(upper, C) == NULL"); | ||
317 | if (wctyg == wctyc) | ||
318 | errx(1, "wctype global == C"); | ||
319 | TEST_R(iswctype, 1, 0x00D0, wctyg); /* Eth */ | ||
320 | TEST_R(iswctype_l, 1, 0x00D0, wctyu, _LOCALE_UTF8); | ||
321 | TEST_R(iswctype_l, 0, 0x00D0, wctyc, _LOCALE_C); | ||
322 | TEST_R(iswctype, 1, 0x0393, wctyg); /* Gamma */ | ||
323 | TEST_R(iswctype_l, 1, 0x0393, wctyu, _LOCALE_UTF8); | ||
324 | TEST_R(iswctype_l, 0, 0x0393, wctyc, _LOCALE_C); | ||
325 | TEST_R(iswctype, 0, 0x2205, wctyg); /* empty set */ | ||
326 | TEST_R(iswctype_l, 0, 0x2205, wctyu, _LOCALE_UTF8); | ||
327 | TEST_R(iswctype_l, 0, 0x2205, wctyc, _LOCALE_C); | ||
328 | wctrg = wctrans("tolower"); | ||
329 | if (wctrg == NULL) | ||
330 | errx(1, "wctrans(tolower) == NULL"); | ||
331 | wctru = wctrans_l("tolower", _LOCALE_UTF8); | ||
332 | if (wctru == NULL) | ||
333 | errx(1, "wctrans(tolower, UTF-8) == NULL"); | ||
334 | if (wctrg != wctru) | ||
335 | errx(1, "wctrans global != UTF-8"); | ||
336 | wctrc = wctrans_l("tolower", _LOCALE_C); | ||
337 | if (wctrc == NULL) | ||
338 | errx(1, "wctrans(tolower, C) == NULL"); | ||
339 | if (wctrg == wctrc) | ||
340 | errx(1, "wctrans global == C"); | ||
341 | TEST_R(towctrans, 0x00FE, 0x00DE, wctrg); /* Thorn */ | ||
342 | TEST_R(towctrans_l, 0x00FE, 0x00DE, wctru, _LOCALE_UTF8); | ||
343 | TEST_R(towctrans_l, 0x00DE, 0x00DE, wctrc, _LOCALE_C); | ||
344 | TEST_R(towctrans, 0x03C6, 0x03A6, wctrg); /* Phi */ | ||
345 | TEST_R(towctrans_l, 0x03C6, 0x03A6, wctru, _LOCALE_UTF8); | ||
346 | TEST_R(towctrans_l, 0x03A6, 0x03A6, wctrc, _LOCALE_C); | ||
347 | TEST_R(towctrans, 0x2207, 0x2207, wctrg); /* Nabla */ | ||
348 | TEST_R(towctrans_l, 0x2207, 0x2207, wctru, _LOCALE_UTF8); | ||
349 | TEST_R(towctrans_l, 0x2207, 0x2207, wctrc, _LOCALE_C); | ||
350 | TEST_R(wcscasecmp, 0, s1, s2); | ||
351 | TEST_R(wcscasecmp_l, 0, s1, s2, _LOCALE_UTF8); | ||
352 | TEST_R(wcscasecmp_l, *s1 - *s2, s1, s2, _LOCALE_C); | ||
353 | TEST_R(wcsncasecmp, 0, s3, s4, 2); | ||
354 | TEST_R(wcsncasecmp_l, 0, s3, s4, 2, _LOCALE_UTF8); | ||
355 | TEST_R(wcsncasecmp_l, *s3 - *s4, s3, s4, 2, _LOCALE_C); | ||
240 | 356 | ||
241 | /* Test non-ctype newlocale(3). */ | 357 | /* Test non-ctype newlocale(3). */ |
242 | TEST_R(newlocale, _LOCALE_C, LC_MESSAGES_MASK, "en_US.UTF-8"); | 358 | TEST_R(newlocale, _LOCALE_C, LC_MESSAGES_MASK, "en_US.UTF-8"); |
243 | 359 | ||
360 | /* Test strerror(3). */ | ||
361 | sego = strerror(EPERM); | ||
362 | segc = strdup(sego); | ||
363 | selo = strerror_l(ENOENT, _LOCALE_C); | ||
364 | selc = strdup(selo); | ||
365 | if (strcmp(sego, segc) != 0) | ||
366 | errx(1, "child: strerror_l clobbered strerror"); | ||
367 | free(segc); | ||
368 | sego = strerror(ESRCH); | ||
369 | if (strcmp(selo, selc) != 0) | ||
370 | errx(1, "child: strerror clobbered strerror_l"); | ||
371 | |||
244 | /* Temporarily switch to the main thread. */ | 372 | /* Temporarily switch to the main thread. */ |
245 | switch_thread(2, SWITCH_SIGNAL | SWITCH_WAIT); | 373 | switch_thread(2, SWITCH_SIGNAL | SWITCH_WAIT); |
374 | if (strcmp(selo, selc) != 0) | ||
375 | errx(1, "child: main clobbered strerror_l"); | ||
376 | free(selc); | ||
246 | 377 | ||
247 | /* Test displaying the global locale while a local one is set. */ | 378 | /* Test displaying the global locale while a local one is set. */ |
248 | TEST_R(setlocale, "C/C.UTF-8/C/C/C/C", LC_ALL, NULL); | 379 | TEST_R(setlocale, "C/C.UTF-8/C/C/C/C", LC_ALL, NULL); |
@@ -268,6 +399,7 @@ int | |||
268 | main(void) | 399 | main(void) |
269 | { | 400 | { |
270 | pthread_t child_thread; | 401 | pthread_t child_thread; |
402 | char *sego, *segc, *selo, *selc; | ||
271 | int irc; | 403 | int irc; |
272 | 404 | ||
273 | /* Initialize environment. */ | 405 | /* Initialize environment. */ |
@@ -294,6 +426,19 @@ main(void) | |||
294 | TEST_R(MB_CUR_MAX, 4); | 426 | TEST_R(MB_CUR_MAX, 4); |
295 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE); | 427 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE); |
296 | 428 | ||
429 | /* Test strerror(3). */ | ||
430 | sego = strerror(EINTR); | ||
431 | segc = strdup(sego); | ||
432 | selo = strerror_l(EIO, _LOCALE_C); | ||
433 | selc = strdup(selo); | ||
434 | if (strcmp(sego, segc) != 0) | ||
435 | errx(1, "main: strerror_l clobbered strerror"); | ||
436 | free(segc); | ||
437 | sego = strerror(ENXIO); | ||
438 | if (strcmp(selo, selc) != 0) | ||
439 | errx(1, "main: strerror clobbered strerror_l"); | ||
440 | free(selc); | ||
441 | |||
297 | /* Let the child do some more tests, then clean up. */ | 442 | /* Let the child do some more tests, then clean up. */ |
298 | switch_thread(3, SWITCH_SIGNAL); | 443 | switch_thread(3, SWITCH_SIGNAL); |
299 | if ((irc = pthread_join(child_thread, NULL)) != 0) | 444 | if ((irc = pthread_join(child_thread, NULL)) != 0) |