1 /* PDCLib testing suite <_PDCLIB_test.h>
2 
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6 
7 /* -------------------------------------------------------------------------- */
8 /* Helper macros for printf() / scanf() tests                                 */
9 /* -------------------------------------------------------------------------- */
10 /* Tucked away in a separate header because these are ugly, complex, and not  */
11 /* needed in 95% of all test cases.                                           */
12 /* -------------------------------------------------------------------------- */
13 
14 /* ...printf() tests */
15 #if defined( _PDCLIB_FILEIO )
16    #define GET_RESULT \
17       rewind( target ); \
18       if ( (int)fread( result_buffer, 1, actual_rc, target ) != actual_rc ) \
19       { \
20           fprintf( stderr, "GET_RESULT failed." ); \
21       }
22    #define RESULT_MISMATCH( act, exp ) strcmp( result_buffer, exp ) != 0
23    #define RESULT_STRING( tgt ) result_buffer
24 #elif defined( _PDCLIB_STRINGIO )
25    #define RESULT_MISMATCH( act, exp ) strcmp( act, exp ) != 0
26    #define GET_RESULT
27    #define RESULT_STRING( tgt ) tgt
28 #endif
29 
30 #ifdef _PDCLIB_FILEIO
31 #define PREP_RESULT_BUFFER char result_buffer[100] = { 0 }; rewind( target );
32 #else
33 #define PREP_RESULT_BUFFER
34 #endif
35 
36 #define GETFMT( fmt, ... ) (fmt)
37 #define PRINTF_TEST( expected_rc, expected_string, ... ) do { \
38         int actual_rc; \
39         PREP_RESULT_BUFFER \
40         actual_rc = testprintf( target, __VA_ARGS__ ); \
41         GET_RESULT \
42         if ( ( actual_rc != expected_rc ) || \
43              ( RESULT_MISMATCH( target, expected_string ) ) ) \
44         { \
45             ++TEST_RESULTS; \
46             fprintf( stderr, \
47                 "FAILED: " __FILE__ " (" _PDCLIB_FILEID "), line %d\n" \
48                 "        format string \"%s\"\n" \
49                 "        expected %2d, \"%s\"\n" \
50                 "        actual   %2d, \"%s\"\n", \
51                  __LINE__, GETFMT(__VA_ARGS__, 0), expected_rc, \
52                  expected_string, actual_rc, RESULT_STRING( target ) ); \
53         } \
54     } while ( 0 )
55 
56 /* ...scanf() tests */
57 #if defined( _PDCLIB_FILEIO )
58     #define PREPARE_SOURCE( input_string ) \
59         source = freopen( NULL, "wb+", source ); \
60         fwrite( input_string, 1, strlen( input_string ), source ); \
61         rewind( source );
62 #elif defined( _PDCLIB_STRINGIO )
63     #define PREPARE_SOURCE( input_string ) \
64         memcpy( source, input_string, sizeof( input_string ) );
65 #endif
66 
67 #define SCANF_TEST( expected_rc, input_string, ... ) do { \
68         int actual_rc; \
69         PREPARE_SOURCE( input_string ); \
70         actual_rc = testscanf( source, __VA_ARGS__ ); \
71         if ( actual_rc != expected_rc ) \
72         { \
73             ++TEST_RESULTS; \
74             fprintf( stderr, "FAILED: " __FILE__ " (" _PDCLIB_FILEID "), line %d\n        expected %2d,        actual   %2d\n", __LINE__, expected_rc, actual_rc ); \
75         } \
76     } while ( 0 )
77 
78 /* Virtually everything in the printf() / scanf() test drivers is heavily
79    depending on the platform, i.e. the width of the integer values. To do
80    proper domain tests, we need the limits of the integers (largest and
81    smallest value), which we can get from <limits.h>. But we also need the
82    string representations of these numbers, to the various bases, which of
83    course vary depending on how the platform defines 'int' and 'long'.
84 */
85 
86 #define sym2v( x ) #x
87 #define sym2s( x ) sym2v( x )
88 
89 #if INT_MAX >> 15 == 1
90 
91 #define UINT_DIG 5
92 #define INT_DIG  5
93 #define INT_DIG_LESS1 "4"
94 #define INT_DIG_PLUS1 "6"
95 #define INT_DIG_PLUS2 "7"
96 #define INT_HEXDIG "FFF"
97 #define INT_hexdig "fff"
98 #define INT_OCTDIG "177777"
99 #define INT_MAX_DEZ_STR  "32767"
100 #define INT_MIN_DEZ_STR  "32768"
101 #define UINT_MAX_DEZ_STR "65535"
102 #define INT_MAX_OCT_STR
103 #define INT_MIN_OCT_STR
104 #define UINT_MAX_OCT_STR
105 #define INT_MAX_HEX_STR
106 #define INT_MIN_HEX_STR
107 #define UINT_MAX_HEX_STR
108 
109 #elif UINT_MAX >> 31 == 1
110 
111 #define UINT_DIG 10
112 #define INT_DIG  10
113 #define INT_DIG_LESS1 "9"
114 #define INT_DIG_PLUS1 "11"
115 #define INT_DIG_PLUS2 "12"
116 #define INT_HEXDIG "FFFFFFF"
117 #define INT_hexdig "fffffff"
118 #define INT_OCTDIG "37777777777"
119 #define INT_MAX_DEZ_STR  "2147483647"
120 #define INT_MIN_DEZ_STR  "2147483648"
121 #define UINT_MAX_DEZ_STR "4294967295"
122 #define INT_MAX_OCT_STR
123 #define INT_MIN_OCT_STR
124 #define UINT_MAX_OCT_STR
125 #define INT_MAX_HEX_STR
126 #define INT_MIN_HEX_STR
127 #define UINT_MAX_HEX_STR
128 
129 #elif UINT_MAX >> 63 == 1
130 
131 #define UINT_DIG 20
132 #define INT_DIG  19
133 #define INT_DIG_LESS1 "18"
134 #define INT_DIG_PLUS1 "20"
135 #define INT_DIG_PLUS2 "21"
136 #define INT_HEXDIG "FFFFFFFFFFFFFFF"
137 #define INT_hexdig "fffffffffffffff"
138 #define INT_OCTDIG "1777777777777777777777"
139 #define INT_MAX_DEZ_STR   "9223372036854775807"
140 #define INT_MIN_DEZ_STR   "9223372036854775808"
141 #define UINT_MAX_DEZ_STR "18446744073709551615"
142 #define INT_MAX_OCT_STR
143 #define INT_MIN_OCT_STR
144 #define UINT_MAX_OCT_STR
145 #define INT_MAX_HEX_STR
146 #define INT_MIN_HEX_STR
147 #define UINT_MAX_HEX_STR
148 
149 #else
150 
151 #error Unsupported width of 'int' (neither 16, 32, nor 64 bit).
152 
153 #endif
154 
155 
156 #if ULONG_MAX >> 31 == 1
157 
158 #define ULONG_DIG 10
159 #define LONG_DIG  10
160 #define LONG_MAX_DEZ_STR  "2147483647"
161 #define LONG_MIN_DEZ_STR  "2147483648"
162 #define ULONG_MAX_DEZ_STR "4294967295"
163 #define LONG_MAX_OCT_STR
164 #define LONG_MIN_OCT_STR
165 #define ULONG_MAX_OCT_STR
166 #define LONG_MAX_HEX_STR
167 #define LONG_MIN_HEX_STR
168 #define ULONG_MAX_HEX_STR
169 
170 #elif ULONG_MAX >> 63 == 1
171 
172 #define ULONG_DIG 20
173 #define LONG_DIG  19
174 #define LONG_MAX_DEZ_STR   "9223372036854775807"
175 #define LONG_MIN_DEZ_STR   "9223372036854775808"
176 #define ULONG_MAX_DEZ_STR "18446744073709551615"
177 #define LONG_MAX_OCT_STR
178 #define LONG_MIN_OCT_STR
179 #define ULONG_MAX_OCT_STR
180 #define LONG_MAX_HEX_STR
181 #define LONG_MIN_HEX_STR
182 #define ULONG_MAX_HEX_STR
183 
184 #else
185 
186 #error Unsupported width of 'long' (neither 32 nor 64 bit).
187 
188 #endif
189 
190 
191 #if ULLONG_MAX >> 63 == 1
192 
193 #define ULLONG_DIG 20
194 #define LLONG_DIG  19
195 #define LLONG_MAX_DEZ_STR   "9223372036854775807"
196 #define LLONG_MIN_DEZ_STR   "9223372036854775808"
197 #define ULLONG_MAX_DEZ_STR "18446744073709551615"
198 #define LLONG_MAX_OCT_STR
199 #define LLONG_MIN_OCT_STR
200 #define ULLONG_MAX_OCT_STR
201 #define LLONG_MAX_HEX_STR
202 #define LLONG_MIN_HEX_STR
203 #define ULLONG_MAX_HEX_STR
204 
205 #elif ULLONG_MAX >> 127 == 1
206 
207 #define ULLONG_DIG 38
208 #define LLONG_DIG  38
209 #define LLONG_MAX_DEZ_STR  "170141183460469231731687303715884105727"
210 #define LLONG_MIN_DEZ_STR  "170141183460469231731687303715884105728"
211 #define ULLONG_MAX_DEZ_STR "340282366920938463463374607431768211455"
212 #define LLONG_MAX_OCT_STR
213 #define LLONG_MIN_OCT_STR
214 #define ULLONG_MAX_OCT_STR
215 #define LLONG_MAX_HEX_STR
216 #define LLONG_MIN_HEX_STR
217 #define ULLONG_MAX_HEX_STR
218 
219 #else
220 
221 #error Unsupported width of 'long long' (neither 64 nor 128 bit).
222 
223 #endif
224