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   warn_count __attribute__ ((unused));	\
87 	int   func_id, seq_num = 0;			\
88 	const char *locale;				\
89 	int   err_exp, ret_flg;				\
90 	int errno_save = 0;				\
91 	_type_ ret_exp;					\
92 	_type_ ret
93 
94 #define TST_DO_TEST(o_func) \
95 	for (loc = 0; strcmp (TST_HEAD (o_func).locale, TST_LOC_end); ++loc)
96 
97 
98 #ifdef __UCLIBC_HAS_LOCALE__
99 #define TST_HEAD_LOCALE(ofunc, s_func) \
100   func_id = TST_HEAD (ofunc).func_id;					      \
101   locale  = TST_HEAD (ofunc).locale;					      \
102   if (setlocale (LC_ALL, locale) == NULL)				      \
103     {									      \
104       fprintf (stderr, "Warning : can't set locale: %s\nskipping ...\n",      \
105 	       locale);							      \
106       result (fp, C_LOCALES, s_func, locale, 0, 0, 0, "can't set locale");    \
107       ++err_count;							      \
108       continue;								      \
109     }
110 #else
111 #define TST_HEAD_LOCALE(ofunc, s_func)					\
112   func_id = TST_HEAD (ofunc).func_id;					\
113   locale  = TST_HEAD (ofunc).locale;					\
114   if (strcmp(locale, "C") == 0)					\
115 	{								\
116 	if (setlocale (LC_ALL, locale) == NULL)						\
117 		{									\
118 		fprintf (stderr, "Warning : can't set locale: %s\nskipping ...\n",	\
119 			locale);							\
120 		result (fp, C_LOCALES, s_func, locale, 0, 0, 0, "can't set locale");	\
121 		++err_count;						\
122 		continue;						\
123 		}							\
124 	}								\
125   else									\
126   	{								\
127 		fprintf (stderr, "Warning : locale %s unsupported\n\n",		\
128 			locale);						\
129 		result (fp, C_LOCALES, s_func, locale, 0, 0, 0, "unsupported");	\
130 		continue;						      	\
131 	}
132 #endif
133 
134 #define TST_DO_REC(ofunc) \
135 	for (rec=0; !TST_IS_LAST (ofunc); ++rec)
136 
137 #define TST_DO_SEQ(_count_) \
138 	for (seq_num=0; seq_num < _count_; seq_num++)
139 
140 #define TST_GET_ERRET(_ofunc_)			\
141 	err_exp = TST_EXPECT (_ofunc_).err_val; \
142 	ret_flg = TST_EXPECT (_ofunc_).ret_flg; \
143 	ret_exp = TST_EXPECT (_ofunc_).ret_val
144 
145 #define TST_GET_ERRET_SEQ(_ofunc_)		    \
146 	err_exp = TST_EXPECT_SEQ (_ofunc_).err_val; \
147 	ret_flg = TST_EXPECT_SEQ (_ofunc_).ret_flg; \
148 	ret_exp = TST_EXPECT_SEQ (_ofunc_).ret_val
149 
150 #define TST_CLEAR_ERRNO \
151 	errno = 0
152 
153 #define TST_SAVE_ERRNO \
154 	errno_save = errno
155 
156 /* Test value of ret and of errno if it should have a value.  */
157 #define TST_IF_RETURN(_s_func_) \
158   if (err_exp != 0)							      \
159     {									      \
160       if (errno_save == err_exp)					      \
161 	{								      \
162 	  result (fp, C_SUCCESS, _s_func_, locale, rec+1, seq_num+1, 1,	      \
163 		  MS_PASSED);						      \
164 	}								      \
165       else								      \
166 	{								      \
167 	  err_count++;							      \
168 	  result (fp, C_FAILURE, _s_func_, locale, rec+1, seq_num+1, 1,	      \
169 		  "the value of errno is different from an expected value");  \
170 	}								      \
171     }									      \
172 									      \
173   if (ret_flg == 1)							      \
174     {									      \
175       if (ret == ret_exp)						      \
176 	{								      \
177 	  result (fp, C_SUCCESS, _s_func_, locale, rec+1, seq_num+1, 2,	      \
178 		  MS_PASSED);						      \
179 	}								      \
180       else								      \
181 	{								      \
182 	  err_count++;							      \
183 	  result (fp, C_FAILURE, _s_func_, locale, rec+1, seq_num+1, 2,	      \
184 		  "the return value is different from an expected value");    \
185 	}								      \
186     }									      \
187   else
188 
189 #define TEX_ERRET_REC(_type_)			\
190 	struct {				\
191 	    TMD_ERRET (_type_);			\
192 	}
193 
194 #define TEX_ERRET_REC_SEQ(_type_, _count_)	\
195 	struct {				\
196 	    struct {				\
197 		TMD_ERRET (_type_);		\
198 	    } seq[ _count_ ];			\
199 	}
200 
201 
202 
203 /* ------------------ FUNCTION: ISW*() ------------------- */
204 
205 #define TST_ISW_STRUCT(_FUNC_, _func_)			\
206 	typedef						\
207 	struct {					\
208 	    wint_t   wc;				\
209 	} TIN_ISW##_FUNC_##_REC;			\
210 	typedef						\
211 	TEX_ERRET_REC (int)   TEX_ISW##_FUNC_##_REC;	\
212 	TMD_RECHEAD (ISW##_FUNC_)
213 
214 #define TST_FUNC_ISW(_FUNC_, _func_) \
215 int									      \
216 tst_isw##_func_ (FILE *fp, int debug_flg)				      \
217 {									      \
218   TST_DECL_VARS(int);							      \
219   wint_t wc;								      \
220   TST_DO_TEST (isw##_func_)						      \
221     {									      \
222       TST_HEAD_LOCALE (isw##_func_, S_ISW##_FUNC_);			      \
223       TST_DO_REC(isw##_func_)						      \
224 	{								      \
225 	  TST_GET_ERRET (isw##_func_);					      \
226 	  wc = TST_INPUT (isw##_func_).wc;				      \
227 	  ret = isw##_func_ (wc);					      \
228 	  if (debug_flg)						      \
229 	    {								      \
230 	      fprintf (stdout, "isw*() [ %s : %d ] ret = %d\n", locale,	      \
231 		       rec+1, ret);					      \
232 	    }								      \
233 									      \
234 	  TST_IF_RETURN (S_ISW##_FUNC_)					      \
235 	    {								      \
236 	      if (ret != 0)						      \
237 		{							      \
238 		  result (fp, C_SUCCESS, S_ISW##_FUNC_, locale, rec+1,	      \
239 			  seq_num+1, 3, MS_PASSED);			      \
240 		}							      \
241 	      else							      \
242 		{							      \
243 		  err_count++;						      \
244 		  result (fp, C_FAILURE, S_ISW##_FUNC_, locale, rec+1,	      \
245 			  seq_num+1, 3,					      \
246 			  "the function returned 0, but should be non-zero"); \
247 		}							      \
248 	    }								      \
249 	}								      \
250     }									      \
251 									      \
252   return err_count;							      \
253 }
254 
255 
256 
257 /* ------------------ FUNCTION: TOW*() ------------------ */
258 
259 #define TST_TOW_STRUCT(_FUNC_, _func_)			\
260 	typedef						\
261 	struct {					\
262 	    wint_t   wc;				\
263 	} TIN_TOW##_FUNC_##_REC;			\
264 	typedef						\
265 	TEX_ERRET_REC (wint_t)	TEX_TOW##_FUNC_##_REC;	\
266 	TMD_RECHEAD (TOW##_FUNC_)
267 
268 #define TST_FUNC_TOW(_FUNC_, _func_)					\
269 int									\
270 tst_tow##_func_ (FILE *fp, int debug_flg)				\
271 {									\
272   TST_DECL_VARS (wint_t);						\
273   wint_t wc;								\
274   TST_DO_TEST (tow##_func_)						\
275     {									\
276       TST_HEAD_LOCALE (tow##_func_, S_TOW##_FUNC_);			\
277       TST_DO_REC (tow##_func_)						\
278 	{								\
279 	  TST_GET_ERRET (tow##_func_);					\
280 	  wc = TST_INPUT (tow##_func_).wc;				\
281 	  ret = tow##_func_ (wc);					\
282 	  if (debug_flg)						\
283 	    {								\
284 	      fprintf (stdout, "tow*() [ %s : %d ] ret = 0x%x\n",	\
285 		       locale, rec+1, ret);				\
286 	    }								\
287 									\
288 	  TST_IF_RETURN (S_TOW##_FUNC_) { };				\
289 	}								\
290     }									\
291 									\
292   return err_count;							\
293 }
294 
295 
296 #endif /* TST_FUNCS_H */
297