1 | /* |
2 | * TEST SUITE FOR MB/WC FUNCTIONS IN C LIBRARY |
3 | * |
4 | * FILE: tst_funcs.h |
5 | * |
6 | * Definitions of macros |
7 | */ |
8 | |
9 | |
10 | #ifndef TST_FUNCS_H |
11 | #define TST_FUNCS_H |
12 | |
13 | #define C_SUCCESS 'S' /* test case test passed */ |
14 | #define C_FAILURE 'F' /* test case failed */ |
15 | #define C_IGNORED 'I' /* test case/result ignored (not tested) */ |
16 | #define C_INVALID 'D' /* test data may be wrong */ |
17 | #define C_LOCALES 'L' /* can't set locale (skip) */ |
18 | |
19 | |
20 | extern int result (FILE * fp, char res, const char *func, const char *loc, |
21 | int rec_no, int seq_num, int case_no, const char *msg); |
22 | |
23 | #define Result(C, S, E, M) \ |
24 | result (fp, (C), (S), locale, rec+1, seq_num+1, (E), (M)) |
25 | |
26 | #define CASE_0 0 |
27 | #define CASE_1 1 |
28 | #define CASE_2 2 |
29 | #define CASE_3 3 |
30 | #define CASE_4 4 |
31 | #define CASE_5 5 |
32 | #define CASE_6 6 |
33 | #define CASE_7 7 |
34 | #define CASE_8 8 |
35 | #define CASE_9 9 |
36 | |
37 | #define MS_PASSED "PASSED" |
38 | #define MS_SPACE " " |
39 | #define MS_FAILED " " |
40 | #define MS_NOTEST "NOTEST" |
41 | #define MS_ABORTU "ABEND0" |
42 | #define MS_ABORT "ABEND1" |
43 | |
44 | #define MK_PASSED 0x00 |
45 | #define MK_SPACE 0x01 |
46 | #define MK_NOTEST 0x02 |
47 | #define MK_ABORTU 0x04 |
48 | #define MK_ABORT 0x08 |
49 | |
50 | |
51 | |
52 | /* ------------------ COMMON MACROS ------------------ */ |
53 | |
54 | #define TST_ABS(x) (((x) > 0) ? (x) : -(x)) |
55 | |
56 | #define TMD_ERRET(_type_) int err_val; \ |
57 | int ret_flg; \ |
58 | _type_ ret_val |
59 | |
60 | #define TMD_RECHEAD(_FUNC_) \ |
61 | \ |
62 | typedef struct { \ |
63 | TIN_##_FUNC_##_REC input; \ |
64 | TEX_##_FUNC_##_REC expect; \ |
65 | int is_last; \ |
66 | } TST_##_FUNC_##_REC; \ |
67 | typedef struct { \ |
68 | TST_HEAD hd; \ |
69 | TST_##_FUNC_##_REC rec[ MAX_LOC_TEST ]; \ |
70 | } TST_##_FUNC_ |
71 | |
72 | #define TST_FTYP(func) tst_##func##_loc |
73 | #define TST_HEAD(func) tst_##func##_loc[ loc ].hd |
74 | #define TST_INPUT(func) tst_##func##_loc[ loc ].rec[ rec ].input |
75 | #define TST_EXPECT(func) tst_##func##_loc[ loc ].rec[ rec ].expect |
76 | #define TST_INPUT_SEQ(func) \ |
77 | tst_##func##_loc[ loc ].rec[ rec ].input.seq[ seq_num ] |
78 | #define TST_EXPECT_SEQ(func) \ |
79 | tst_##func##_loc[ loc ].rec[ rec ].expect.seq[ seq_num ] |
80 | #define TST_IS_LAST(func) \ |
81 | tst_##func##_loc[ loc ].rec[ rec ].is_last |
82 | |
83 | |
84 | #define TST_DECL_VARS(_type_) \ |
85 | int loc, rec, err_count = 0; \ |
86 | int seq_num = 0; \ |
87 | const char *locale; \ |
88 | int err_exp, ret_flg; \ |
89 | int errno_save = 0; \ |
90 | _type_ ret_exp; \ |
91 | _type_ ret |
92 | |
93 | #define TST_DO_TEST(o_func) \ |
94 | for (loc = 0; strcmp (TST_HEAD (o_func).locale, TST_LOC_end); ++loc) |
95 | |
96 | |
97 | #define TST_HEAD_LOCALE(ofunc, s_func) \ |
98 | locale = TST_HEAD (ofunc).locale; \ |
99 | if (setlocale (LC_ALL, locale) == NULL) \ |
100 | { \ |
101 | fprintf (stderr, "Warning : can't set locale: %s\nskipping ...\n", \ |
102 | locale); \ |
103 | result (fp, C_LOCALES, s_func, locale, 0, 0, 0, "can't set locale"); \ |
104 | ++err_count; \ |
105 | continue; \ |
106 | } |
107 | |
108 | #define TST_DO_REC(ofunc) \ |
109 | for (rec=0; !TST_IS_LAST (ofunc); ++rec) |
110 | |
111 | #define TST_DO_SEQ(_count_) \ |
112 | for (seq_num=0; seq_num < _count_; seq_num++) |
113 | |
114 | #define TST_GET_ERRET(_ofunc_) \ |
115 | err_exp = TST_EXPECT (_ofunc_).err_val; \ |
116 | ret_flg = TST_EXPECT (_ofunc_).ret_flg; \ |
117 | ret_exp = TST_EXPECT (_ofunc_).ret_val |
118 | |
119 | #define TST_GET_ERRET_SEQ(_ofunc_) \ |
120 | err_exp = TST_EXPECT_SEQ (_ofunc_).err_val; \ |
121 | ret_flg = TST_EXPECT_SEQ (_ofunc_).ret_flg; \ |
122 | ret_exp = TST_EXPECT_SEQ (_ofunc_).ret_val |
123 | |
124 | #define TST_CLEAR_ERRNO \ |
125 | errno = 0 |
126 | |
127 | #define TST_SAVE_ERRNO \ |
128 | errno_save = errno |
129 | |
130 | /* Test value of ret and of errno if it should have a value. */ |
131 | #define TST_IF_RETURN(_s_func_) \ |
132 | if (err_exp != 0) \ |
133 | { \ |
134 | if (errno_save == err_exp) \ |
135 | { \ |
136 | result (fp, C_SUCCESS, _s_func_, locale, rec+1, seq_num+1, 1, \ |
137 | MS_PASSED); \ |
138 | } \ |
139 | else \ |
140 | { \ |
141 | err_count++; \ |
142 | result (fp, C_FAILURE, _s_func_, locale, rec+1, seq_num+1, 1, \ |
143 | "the value of errno is different from an expected value"); \ |
144 | } \ |
145 | } \ |
146 | \ |
147 | if (ret_flg == 1) \ |
148 | { \ |
149 | if (ret == ret_exp) \ |
150 | { \ |
151 | result (fp, C_SUCCESS, _s_func_, locale, rec+1, seq_num+1, 2, \ |
152 | MS_PASSED); \ |
153 | } \ |
154 | else \ |
155 | { \ |
156 | err_count++; \ |
157 | result (fp, C_FAILURE, _s_func_, locale, rec+1, seq_num+1, 2, \ |
158 | "the return value is different from an expected value"); \ |
159 | } \ |
160 | } \ |
161 | else |
162 | |
163 | #define TEX_ERRET_REC(_type_) \ |
164 | struct { \ |
165 | TMD_ERRET (_type_); \ |
166 | } |
167 | |
168 | #define TEX_ERRET_REC_SEQ(_type_, _count_) \ |
169 | struct { \ |
170 | struct { \ |
171 | TMD_ERRET (_type_); \ |
172 | } seq[ _count_ ]; \ |
173 | } |
174 | |
175 | |
176 | |
177 | /* ------------------ FUNCTION: ISW*() ------------------- */ |
178 | |
179 | #define TST_ISW_STRUCT(_FUNC_, _func_) \ |
180 | typedef \ |
181 | struct { \ |
182 | wint_t wc; \ |
183 | } TIN_ISW##_FUNC_##_REC; \ |
184 | typedef \ |
185 | TEX_ERRET_REC (int) TEX_ISW##_FUNC_##_REC; \ |
186 | TMD_RECHEAD (ISW##_FUNC_) |
187 | |
188 | #define TST_FUNC_ISW(_FUNC_, _func_) \ |
189 | int \ |
190 | tst_isw##_func_ (FILE *fp, int debug_flg) \ |
191 | { \ |
192 | TST_DECL_VARS(int); \ |
193 | wint_t wc; \ |
194 | TST_DO_TEST (isw##_func_) \ |
195 | { \ |
196 | TST_HEAD_LOCALE (isw##_func_, S_ISW##_FUNC_); \ |
197 | TST_DO_REC(isw##_func_) \ |
198 | { \ |
199 | TST_GET_ERRET (isw##_func_); \ |
200 | wc = TST_INPUT (isw##_func_).wc; \ |
201 | ret = isw##_func_ (wc); \ |
202 | if (debug_flg) \ |
203 | { \ |
204 | fprintf (stdout, "isw*() [ %s : %d ] ret = %d\n", locale, \ |
205 | rec+1, ret); \ |
206 | } \ |
207 | \ |
208 | TST_IF_RETURN (S_ISW##_FUNC_) \ |
209 | { \ |
210 | if (ret != 0) \ |
211 | { \ |
212 | result (fp, C_SUCCESS, S_ISW##_FUNC_, locale, rec+1, \ |
213 | seq_num+1, 3, MS_PASSED); \ |
214 | } \ |
215 | else \ |
216 | { \ |
217 | err_count++; \ |
218 | result (fp, C_FAILURE, S_ISW##_FUNC_, locale, rec+1, \ |
219 | seq_num+1, 3, \ |
220 | "the function returned 0, but should be non-zero"); \ |
221 | } \ |
222 | } \ |
223 | } \ |
224 | } \ |
225 | \ |
226 | return err_count; \ |
227 | } |
228 | |
229 | |
230 | |
231 | /* ------------------ FUNCTION: TOW*() ------------------ */ |
232 | |
233 | #define TST_TOW_STRUCT(_FUNC_, _func_) \ |
234 | typedef \ |
235 | struct { \ |
236 | wint_t wc; \ |
237 | } TIN_TOW##_FUNC_##_REC; \ |
238 | typedef \ |
239 | TEX_ERRET_REC (wint_t) TEX_TOW##_FUNC_##_REC; \ |
240 | TMD_RECHEAD (TOW##_FUNC_) |
241 | |
242 | #define TST_FUNC_TOW(_FUNC_, _func_) \ |
243 | int \ |
244 | tst_tow##_func_ (FILE *fp, int debug_flg) \ |
245 | { \ |
246 | TST_DECL_VARS (wint_t); \ |
247 | wint_t wc; \ |
248 | TST_DO_TEST (tow##_func_) \ |
249 | { \ |
250 | TST_HEAD_LOCALE (tow##_func_, S_TOW##_FUNC_); \ |
251 | TST_DO_REC (tow##_func_) \ |
252 | { \ |
253 | TST_GET_ERRET (tow##_func_); \ |
254 | wc = TST_INPUT (tow##_func_).wc; \ |
255 | ret = tow##_func_ (wc); \ |
256 | if (debug_flg) \ |
257 | { \ |
258 | fprintf (stdout, "tow*() [ %s : %d ] ret = 0x%x\n", \ |
259 | locale, rec+1, ret); \ |
260 | } \ |
261 | \ |
262 | TST_IF_RETURN (S_TOW##_FUNC_) { }; \ |
263 | } \ |
264 | } \ |
265 | \ |
266 | return err_count; \ |
267 | } |
268 | |
269 | |
270 | #endif /* TST_FUNCS_H */ |
271 | |