diff options
| author | schwarze <> | 2017-08-16 13:23:56 +0000 |
|---|---|---|
| committer | schwarze <> | 2017-08-16 13:23:56 +0000 |
| commit | a23a965414c121d5c0d14df50e0e085af78cce60 (patch) | |
| tree | d307e0aa6598e9eed20e0c1ee0d24dd2cccb394c | |
| parent | 0d02667578f313d232fc4590424e67b1e2824dc9 (diff) | |
| download | openbsd-a23a965414c121d5c0d14df50e0e085af78cce60.tar.gz openbsd-a23a965414c121d5c0d14df50e0e085af78cce60.tar.bz2 openbsd-a23a965414c121d5c0d14df50e0e085af78cce60.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)
Diffstat (limited to '')
| -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) |
