diff options
author | schwarze <> | 2017-08-15 23:46:51 +0000 |
---|---|---|
committer | schwarze <> | 2017-08-15 23:46:51 +0000 |
commit | a2bafb65aadaf63075b88786093b416231dcaaf4 (patch) | |
tree | 7f6891f4b223a43936c538935625b15586dfaba2 /src | |
parent | 037380a6241095814abcee8e70fc14d1638c07d3 (diff) | |
download | openbsd-a2bafb65aadaf63075b88786093b416231dcaaf4.tar.gz openbsd-a2bafb65aadaf63075b88786093b416231dcaaf4.tar.bz2 openbsd-a2bafb65aadaf63075b88786093b416231dcaaf4.zip |
refactor in preparation for testing more functions; no functional change
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libc/locale/uselocale/Makefile | 3 | ||||
-rw-r--r-- | src/regress/lib/libc/locale/uselocale/uselocale.c | 228 |
2 files changed, 117 insertions, 114 deletions
diff --git a/src/regress/lib/libc/locale/uselocale/Makefile b/src/regress/lib/libc/locale/uselocale/Makefile index 45c3b7e807..3c3f487df8 100644 --- a/src/regress/lib/libc/locale/uselocale/Makefile +++ b/src/regress/lib/libc/locale/uselocale/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2017/08/10 14:45:42 schwarze Exp $ | 1 | # $OpenBSD: Makefile,v 1.2 2017/08/15 23:46:51 schwarze Exp $ |
2 | 2 | ||
3 | PROG = uselocale | 3 | PROG = uselocale |
4 | CFLAGS += -Wno-macro-redefined | ||
4 | LDFLAGS += -pthread | 5 | LDFLAGS += -pthread |
5 | 6 | ||
6 | run-regress-${PROG}: ${PROG} | 7 | run-regress-${PROG}: ${PROG} |
diff --git a/src/regress/lib/libc/locale/uselocale/uselocale.c b/src/regress/lib/libc/locale/uselocale/uselocale.c index a40f77397a..c33c1e21fa 100644 --- a/src/regress/lib/libc/locale/uselocale/uselocale.c +++ b/src/regress/lib/libc/locale/uselocale/uselocale.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* $OpenBSD: uselocale.c,v 1.1 2017/08/10 14:45:42 schwarze Exp $ */ | 1 | /* $OpenBSD: uselocale.c,v 1.2 2017/08/15 23:46:51 schwarze Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> | 3 | * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> |
4 | * Copyright (c) 2015 Sebastien Marie <semarie@openbsd.org> | ||
5 | * | 4 | * |
6 | * Permission to use, copy, modify, and distribute this software for any | 5 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -22,93 +21,96 @@ | |||
22 | #include <pthread.h> | 21 | #include <pthread.h> |
23 | #include <stdlib.h> | 22 | #include <stdlib.h> |
24 | #include <string.h> | 23 | #include <string.h> |
25 | #include <time.h> | ||
26 | 24 | ||
25 | /* Keep in sync with /usr/src/lib/libc/locale/rune.h. */ | ||
27 | #define _LOCALE_NONE (locale_t)0 | 26 | #define _LOCALE_NONE (locale_t)0 |
28 | #define _LOCALE_C (locale_t)1 | 27 | #define _LOCALE_C (locale_t)1 |
29 | #define _LOCALE_UTF8 (locale_t)2 | 28 | #define _LOCALE_UTF8 (locale_t)2 |
30 | #define _LOCALE_BAD (locale_t)3 | 29 | #define _LOCALE_BAD (locale_t)3 |
31 | 30 | ||
32 | #define SWITCH_SIGNAL 1 | 31 | /* Options for switch_thread() below. */ |
33 | #define SWITCH_WAIT 2 | 32 | #define SWITCH_SIGNAL 1 /* Call pthread_cond_signal(3). */ |
33 | #define SWITCH_WAIT 2 /* Call pthread_cond_timedwait(3). */ | ||
34 | |||
35 | /* Options for TESTFUNC(). */ | ||
36 | #define TOPT_ERR (1 << 0) | ||
37 | #define TOPT_STR (1 << 1) | ||
34 | 38 | ||
35 | /* | 39 | /* |
36 | * test helpers for __LINE__ | 40 | * Generate one test function for a specific interface. |
41 | * Fn = function name | ||
42 | * Ft = function return type | ||
43 | * FUNCPARA = function parameter list with types and names | ||
44 | * FUNCARGS = function argument list, names only, no types | ||
45 | * Af = format string to print the arguments | ||
46 | * Rf = format string to print the return value | ||
47 | * Op = options for the test function, see above | ||
48 | * line = source code line number in this test file | ||
49 | * ee = expected error number | ||
50 | * er = expected return value | ||
51 | * ar = actual return value | ||
52 | * errno = actual error number (global) | ||
37 | */ | 53 | */ |
38 | #define test_newlocale(_e, _ee, _m, _l) \ | 54 | #define TESTFUNC(Fn, Ft, Af, Rf, Op) \ |
39 | _test_newlocale(_e, _ee, _m, _l, __LINE__) | 55 | static void \ |
40 | #define test_duplocale(_e, _ee, _l) _test_duplocale(_e, _ee, _l, __LINE__) | 56 | _test_##Fn(int line, int ee, Ft er, FUNCPARA) \ |
41 | #define test_uselocale(_e, _ee, _l) _test_uselocale(_e, _ee, _l, __LINE__) | 57 | { \ |
42 | #define test_setlocale(_e, _c, _l) _test_setlocale(_e, _c, _l, __LINE__) | 58 | Ft ar; \ |
43 | #define test_MB_CUR_MAX(_e) _test_MB_CUR_MAX(_e, __LINE__) | 59 | errno = 0; \ |
44 | 60 | ar = Fn(FUNCARGS); \ | |
45 | 61 | if (Op & TOPT_STR) { \ | |
46 | static void | 62 | if (er == (Ft)NULL) \ |
47 | _test_newlocale(locale_t expected, int exp_err, | 63 | er = (Ft)"NULL"; \ |
48 | int mask, const char *locname, int line) | 64 | if (ar == (Ft)NULL) \ |
49 | { | 65 | ar = (Ft)"NULL"; \ |
50 | locale_t result = newlocale(mask, locname, _LOCALE_NONE); | 66 | } \ |
51 | 67 | if (Op & TOPT_STR ? strcmp((const char *)er, (const char *)ar) \ | |
52 | if (result != expected) | 68 | : ar != er) \ |
53 | errx(1, "[%d] newlocale(%d, \"%s\")=\"%d\" [expected: \"%d\"]", | 69 | errx(1, "[%d] %s(" Af ")=" Rf " [exp: " Rf "]", \ |
54 | line, mask, locname, (int)result, (int)expected); | 70 | line, #Fn, FUNCARGS, ar, er); \ |
55 | if (errno != exp_err) | 71 | if (Op & TOPT_ERR && errno != ee) \ |
56 | errx(1, "[%d] newlocale(%d, \"%s\") errno=\"%d\" [expected:" | 72 | errx(1, "[%d] %s(" Af ") errno=%d [exp: %d]", \ |
57 | " \"%d\"]", line, mask, locname, errno, exp_err); | 73 | line, #Fn, FUNCARGS, errno, ee); \ |
58 | errno = 0; | ||
59 | } | 74 | } |
60 | 75 | ||
61 | static void | 76 | /* |
62 | _test_duplocale(locale_t expected, int exp_err, locale_t oldloc, int line) | 77 | * Test functions for all tested interfaces. |
63 | { | 78 | */ |
64 | locale_t result = duplocale(oldloc); | 79 | #define FUNCPARA int mask, const char *locname |
80 | #define FUNCARGS mask, locname, _LOCALE_NONE | ||
81 | TESTFUNC(newlocale, locale_t, "%d, %s, %p", "%p", TOPT_ERR) | ||
65 | 82 | ||
66 | if (result != expected) | 83 | #define FUNCPARA locale_t locale |
67 | errx(1, "[%d] duplocale(%d)=\"%d\" [expected: \"%d\"]", | 84 | #define FUNCARGS locale |
68 | line, (int)oldloc, (int)result, (int)expected); | 85 | TESTFUNC(duplocale, locale_t, "%p", "%p", TOPT_ERR) |
69 | if (errno != exp_err) | 86 | TESTFUNC(uselocale, locale_t, "%p", "%p", TOPT_ERR) |
70 | errx(1, "[%d] duplocale(%d) errno=\"%d\" [expected:" | ||
71 | " \"%d\"]", line, (int)oldloc, errno, exp_err); | ||
72 | errno = 0; | ||
73 | } | ||
74 | 87 | ||
75 | static void | 88 | #define FUNCPARA int category, char *locname |
76 | _test_uselocale(locale_t expected, int exp_err, locale_t newloc, int line) | 89 | #define FUNCARGS category, locname |
77 | { | 90 | TESTFUNC(setlocale, const char *, "%d, %s", "%s", TOPT_STR) |
78 | locale_t result = uselocale(newloc); | ||
79 | |||
80 | if (result != expected) | ||
81 | errx(1, "[%d] uselocale(%d)=\"%d\" [expected: \"%d\"]", | ||
82 | line, (int)newloc, (int)result, (int)expected); | ||
83 | if (errno != exp_err) | ||
84 | errx(1, "[%d] uselocale(%d) errno=\"%d\" [expected:" | ||
85 | " \"%d\"]", line, (int)newloc, errno, exp_err); | ||
86 | errno = 0; | ||
87 | } | ||
88 | 91 | ||
89 | static void | 92 | static void |
90 | _test_setlocale(const char *expected, int category, char *locale, int line) | 93 | _test_MB_CUR_MAX(int line, int ee, size_t ar) |
91 | { | 94 | { |
92 | const char *result = setlocale(category, locale); | 95 | if (MB_CUR_MAX != ar) |
93 | 96 | errx(1, "[%d] MB_CUR_MAX=%zd [exp: %zd]", | |
94 | if (expected == NULL) | 97 | line, MB_CUR_MAX, ar); |
95 | expected = "(null)"; | ||
96 | if (result == NULL) | ||
97 | result = "(null)"; | ||
98 | if (strcmp(expected, result) != 0) | ||
99 | errx(1, "[%d] setlocale(%d, \"%s\")=\"%s\" [expected: \"%s\"]", | ||
100 | line, category, locale, result, expected); | ||
101 | errno = 0; | ||
102 | } | 98 | } |
103 | 99 | ||
104 | static void | 100 | /* |
105 | _test_MB_CUR_MAX(size_t expected, int line) | 101 | * Test macros: |
106 | { | 102 | * TEST_R(funcname, er, arguments) if you expect errno == 0. |
107 | if (MB_CUR_MAX != expected) | 103 | * TEST_ER(funcname, ee, er, arguments) otherwise. |
108 | errx(1, "[%d] MB_CUR_MAX=%ld [expected %ld]", | 104 | */ |
109 | line, MB_CUR_MAX, expected); | 105 | #define TEST_R(Fn, ...) _test_##Fn(__LINE__, 0, __VA_ARGS__) |
110 | } | 106 | #define TEST_ER(Fn, ...) _test_##Fn(__LINE__, __VA_ARGS__) |
111 | 107 | ||
108 | /* | ||
109 | * SWITCH_SIGNAL wakes the other thread. | ||
110 | * SWITCH_WAIT goes to sleep. | ||
111 | * Both can be combined. | ||
112 | * The step argument is used for error reporting only. | ||
113 | */ | ||
112 | static void | 114 | static void |
113 | switch_thread(int step, int flags) | 115 | switch_thread(int step, int flags) |
114 | { | 116 | { |
@@ -154,67 +156,67 @@ static void * | |||
154 | child_func(void *arg) | 156 | child_func(void *arg) |
155 | { | 157 | { |
156 | /* Test invalid newlocale(3) arguments. */ | 158 | /* Test invalid newlocale(3) arguments. */ |
157 | test_newlocale(_LOCALE_NONE, EINVAL, LC_CTYPE_MASK, NULL); | 159 | TEST_ER(newlocale, EINVAL, _LOCALE_NONE, LC_CTYPE_MASK, NULL); |
158 | test_MB_CUR_MAX(1); | 160 | TEST_R(MB_CUR_MAX, 1); |
159 | test_newlocale(_LOCALE_NONE, EINVAL, LC_ALL_MASK + 1, "C.UTF-8"); | 161 | TEST_ER(newlocale, EINVAL, _LOCALE_NONE, LC_ALL_MASK + 1, "C.UTF-8"); |
160 | test_MB_CUR_MAX(1); | 162 | TEST_R(MB_CUR_MAX, 1); |
161 | test_newlocale(_LOCALE_NONE, ENOENT, LC_COLLATE_MASK, "C.INV"); | 163 | TEST_ER(newlocale, ENOENT, _LOCALE_NONE, LC_COLLATE_MASK, "C.INV"); |
162 | test_MB_CUR_MAX(1); | 164 | TEST_R(MB_CUR_MAX, 1); |
163 | setenv("LC_TIME", "C.INV", 1); | 165 | setenv("LC_TIME", "C.INV", 1); |
164 | test_newlocale(_LOCALE_NONE, ENOENT, LC_TIME_MASK, ""); | 166 | TEST_ER(newlocale, ENOENT, _LOCALE_NONE, LC_TIME_MASK, ""); |
165 | unsetenv("LC_TIME"); | 167 | unsetenv("LC_TIME"); |
166 | test_MB_CUR_MAX(1); | 168 | TEST_R(MB_CUR_MAX, 1); |
167 | setenv("LC_CTYPE", "C.INV", 1); | 169 | setenv("LC_CTYPE", "C.INV", 1); |
168 | test_newlocale(_LOCALE_NONE, ENOENT, LC_CTYPE_MASK, ""); | 170 | TEST_ER(newlocale, ENOENT, _LOCALE_NONE, LC_CTYPE_MASK, ""); |
169 | test_MB_CUR_MAX(1); | 171 | TEST_R(MB_CUR_MAX, 1); |
170 | 172 | ||
171 | /* Test duplocale(3). */ | 173 | /* Test duplocale(3). */ |
172 | test_duplocale(_LOCALE_NONE, EINVAL, _LOCALE_UTF8); | 174 | TEST_ER(duplocale, EINVAL, _LOCALE_NONE, _LOCALE_UTF8); |
173 | test_duplocale(_LOCALE_C, 0, _LOCALE_C); | 175 | TEST_R(duplocale, _LOCALE_C, _LOCALE_C); |
174 | test_duplocale(_LOCALE_C, 0, LC_GLOBAL_LOCALE); | 176 | TEST_R(duplocale, _LOCALE_C, LC_GLOBAL_LOCALE); |
175 | 177 | ||
176 | /* Test premature UTF-8 uselocale(3). */ | 178 | /* Test premature UTF-8 uselocale(3). */ |
177 | test_uselocale(_LOCALE_NONE, EINVAL, _LOCALE_UTF8); | 179 | TEST_ER(uselocale, EINVAL, _LOCALE_NONE, _LOCALE_UTF8); |
178 | test_MB_CUR_MAX(1); | 180 | TEST_R(MB_CUR_MAX, 1); |
179 | test_uselocale(LC_GLOBAL_LOCALE, 0, _LOCALE_NONE); | 181 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE); |
180 | 182 | ||
181 | /* Test UTF-8 initialization. */ | 183 | /* Test UTF-8 initialization. */ |
182 | setenv("LC_CTYPE", "C.UTF-8", 1); | 184 | setenv("LC_CTYPE", "C.UTF-8", 1); |
183 | test_newlocale(_LOCALE_UTF8, 0, LC_CTYPE_MASK, ""); | 185 | TEST_R(newlocale, _LOCALE_UTF8, LC_CTYPE_MASK, ""); |
184 | unsetenv("LC_CTYPE"); | 186 | unsetenv("LC_CTYPE"); |
185 | test_MB_CUR_MAX(1); | 187 | TEST_R(MB_CUR_MAX, 1); |
186 | test_duplocale(_LOCALE_UTF8, 0, _LOCALE_UTF8); | 188 | TEST_R(duplocale, _LOCALE_UTF8, _LOCALE_UTF8); |
187 | 189 | ||
188 | /* Test invalid uselocale(3) argument. */ | 190 | /* Test invalid uselocale(3) argument. */ |
189 | test_uselocale(_LOCALE_NONE, EINVAL, _LOCALE_BAD); | 191 | TEST_ER(uselocale, EINVAL, _LOCALE_NONE, _LOCALE_BAD); |
190 | test_MB_CUR_MAX(1); | 192 | TEST_R(MB_CUR_MAX, 1); |
191 | test_uselocale(LC_GLOBAL_LOCALE, 0, _LOCALE_NONE); | 193 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE); |
192 | 194 | ||
193 | /* Test switching the thread locale. */ | 195 | /* Test switching the thread locale. */ |
194 | test_uselocale(LC_GLOBAL_LOCALE, 0, _LOCALE_UTF8); | 196 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_UTF8); |
195 | test_MB_CUR_MAX(4); | 197 | TEST_R(MB_CUR_MAX, 4); |
196 | test_uselocale(_LOCALE_UTF8, 0, _LOCALE_NONE); | 198 | TEST_R(uselocale, _LOCALE_UTF8, _LOCALE_NONE); |
197 | 199 | ||
198 | /* Test non-ctype newlocale(3). */ | 200 | /* Test non-ctype newlocale(3). */ |
199 | test_newlocale(_LOCALE_C, 0, LC_MESSAGES_MASK, "en_US.UTF-8"); | 201 | TEST_R(newlocale, _LOCALE_C, LC_MESSAGES_MASK, "en_US.UTF-8"); |
200 | 202 | ||
201 | /* Temporarily switch to the main thread. */ | 203 | /* Temporarily switch to the main thread. */ |
202 | switch_thread(2, SWITCH_SIGNAL | SWITCH_WAIT); | 204 | switch_thread(2, SWITCH_SIGNAL | SWITCH_WAIT); |
203 | 205 | ||
204 | /* Test displaying the global locale while a local one is set. */ | 206 | /* Test displaying the global locale while a local one is set. */ |
205 | test_setlocale("C/C.UTF-8/C/C/C/C", LC_ALL, NULL); | 207 | TEST_R(setlocale, "C/C.UTF-8/C/C/C/C", LC_ALL, NULL); |
206 | 208 | ||
207 | /* Test switching the thread locale back. */ | 209 | /* Test switching the thread locale back. */ |
208 | test_MB_CUR_MAX(4); | 210 | TEST_R(MB_CUR_MAX, 4); |
209 | test_duplocale(_LOCALE_UTF8, 0, LC_GLOBAL_LOCALE); | 211 | TEST_R(duplocale, _LOCALE_UTF8, LC_GLOBAL_LOCALE); |
210 | test_uselocale(_LOCALE_UTF8, 0, _LOCALE_C); | 212 | TEST_R(uselocale, _LOCALE_UTF8, _LOCALE_C); |
211 | test_MB_CUR_MAX(1); | 213 | TEST_R(MB_CUR_MAX, 1); |
212 | test_uselocale(_LOCALE_C, 0, _LOCALE_NONE); | 214 | TEST_R(uselocale, _LOCALE_C, _LOCALE_NONE); |
213 | 215 | ||
214 | /* Test switching back to the global locale. */ | 216 | /* Test switching back to the global locale. */ |
215 | test_uselocale(_LOCALE_C, 0, LC_GLOBAL_LOCALE); | 217 | TEST_R(uselocale, _LOCALE_C, LC_GLOBAL_LOCALE); |
216 | test_MB_CUR_MAX(4); | 218 | TEST_R(MB_CUR_MAX, 4); |
217 | test_uselocale(LC_GLOBAL_LOCALE, 0, _LOCALE_NONE); | 219 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE); |
218 | 220 | ||
219 | /* Hand control back to the main thread. */ | 221 | /* Hand control back to the main thread. */ |
220 | switch_thread(4, SWITCH_SIGNAL); | 222 | switch_thread(4, SWITCH_SIGNAL); |
@@ -243,13 +245,13 @@ main(void) | |||
243 | switch_thread(1, SWITCH_WAIT); | 245 | switch_thread(1, SWITCH_WAIT); |
244 | 246 | ||
245 | /* Check that the global locale is undisturbed. */ | 247 | /* Check that the global locale is undisturbed. */ |
246 | test_setlocale("C", LC_ALL, NULL); | 248 | TEST_R(setlocale, "C", LC_ALL, NULL); |
247 | test_MB_CUR_MAX(1); | 249 | TEST_R(MB_CUR_MAX, 1); |
248 | 250 | ||
249 | /* Test setting the globale locale. */ | 251 | /* Test setting the globale locale. */ |
250 | test_setlocale("C.UTF-8", LC_CTYPE, "C.UTF-8"); | 252 | TEST_R(setlocale, "C.UTF-8", LC_CTYPE, "C.UTF-8"); |
251 | test_MB_CUR_MAX(4); | 253 | TEST_R(MB_CUR_MAX, 4); |
252 | test_uselocale(LC_GLOBAL_LOCALE, 0, _LOCALE_NONE); | 254 | TEST_R(uselocale, LC_GLOBAL_LOCALE, _LOCALE_NONE); |
253 | 255 | ||
254 | /* Let the child do some more tests, then clean up. */ | 256 | /* Let the child do some more tests, then clean up. */ |
255 | switch_thread(3, SWITCH_SIGNAL); | 257 | switch_thread(3, SWITCH_SIGNAL); |