21
21
#include "libc/str/str.h"
22
22
#include "libc/testlib/testlib.h"
23
23
24
+ static void check_single_double (const char * fmt , const char * expected_str ,
25
+ double value ) {
26
+ char buf [30 ] = {0 };
27
+ int i = snprintf (buf , sizeof (buf ), fmt , value );
28
+
29
+ ASSERT_GE (sizeof (buf ), strlen (expected_str ));
30
+ ASSERT_EQ (strlen (expected_str ), i );
31
+ ASSERT_STREQ (expected_str , buf );
32
+ while (i < sizeof (buf ))
33
+ ASSERT_EQ ('\0' , buf [i ++ ]);
34
+ }
35
+
36
+ static void check_single_long_double (const char * fmt , const char * expected_str ,
37
+ long double value ) {
38
+ char buf [30 ] = {0 };
39
+ int i = snprintf (buf , sizeof (buf ), fmt , value );
40
+
41
+ ASSERT_GE (sizeof (buf ), strlen (expected_str ));
42
+ ASSERT_EQ (strlen (expected_str ), i );
43
+ ASSERT_STREQ (expected_str , buf );
44
+ while (i < sizeof (buf ))
45
+ ASSERT_EQ ('\0' , buf [i ++ ]);
46
+ }
47
+
48
+ void check_single_long_double_arr_allowed (
49
+ const char * fmt , const char * allowed_strs [], long double value ) {
50
+ char buf [30 ] = {0 };
51
+ int res = snprintf (buf , sizeof (buf ), fmt , value );
52
+
53
+ for (size_t i = 0 ; allowed_strs [i ] != NULL ; ++ i )
54
+ if (strlen (allowed_strs [i ]) == res && strcmp (allowed_strs [i ], buf ) == 0 )
55
+ return ;
56
+
57
+ printf ("Failed to find matching str for %`'s, allowed strs:\n" , buf );
58
+ for (size_t i = 0 ; allowed_strs [i ] != NULL ; ++ i )
59
+ printf ("- %`'s\n" , allowed_strs [i ]);
60
+ fflush (stdout );
61
+ ASSERT_EQ (false, true);
62
+ }
63
+
64
+ static void check_single_int (const char * fmt , const char * expected_str ,
65
+ int value ) {
66
+ char buf [30 ] = {0 };
67
+ int i = snprintf (buf , sizeof (buf ), fmt , value );
68
+
69
+ ASSERT_GE (sizeof (buf ), strlen (expected_str ));
70
+ ASSERT_EQ (strlen (expected_str ), i );
71
+ ASSERT_STREQ (expected_str , buf );
72
+ while (i < sizeof (buf ))
73
+ ASSERT_EQ ('\0' , buf [i ++ ]);
74
+ }
75
+
76
+ static void check_single_wint_t (const char * fmt , const char * expected_str ,
77
+ wint_t value ) {
78
+ char buf [30 ] = {0 };
79
+ int i = snprintf (buf , sizeof (buf ), fmt , value );
80
+
81
+ ASSERT_GE (sizeof (buf ), strlen (expected_str ));
82
+ ASSERT_EQ (strlen (expected_str ), i );
83
+ ASSERT_STREQ (expected_str , buf );
84
+ while (i < sizeof (buf ))
85
+ ASSERT_EQ ('\0' , buf [i ++ ]);
86
+ }
87
+
24
88
TEST (snprintf , testVeryLargePrecision ) {
25
89
char buf [512 ] = {};
26
90
int i = snprintf (buf , sizeof (buf ), "%.9999u" , 10 );
@@ -30,59 +94,21 @@ TEST(snprintf, testVeryLargePrecision) {
30
94
}
31
95
32
96
TEST (snprintf , testPlusFlagOnChar ) {
33
- char buf [10 ] = {};
34
- int i = snprintf (buf , sizeof (buf ), "%+c" , '=' );
35
-
36
- ASSERT_EQ (1 , i );
37
- ASSERT_STREQ ("=" , buf );
97
+ check_single_int ("%+c" , "=" , '=' );
38
98
}
39
99
40
100
TEST (snprintf , testInf ) {
41
- char buf [10 ] = {};
42
- int i = snprintf (buf , sizeof (buf ), "%f" , 1.0 / 0.0 );
43
-
44
- ASSERT_EQ (3 , i );
45
- ASSERT_STREQ ("inf" , buf );
46
-
47
- memset (buf , '\0' , 4 );
48
- i = snprintf (buf , sizeof (buf ), "%Lf" , 1.0L / 0.0L );
49
- ASSERT_EQ (3 , i );
50
- ASSERT_STREQ ("inf" , buf );
51
-
52
- memset (buf , '\0' , 4 );
53
- i = snprintf (buf , sizeof (buf ), "%e" , 1.0 / 0.0 );
54
- ASSERT_EQ (3 , i );
55
- ASSERT_STREQ ("inf" , buf );
56
-
57
- memset (buf , '\0' , 4 );
58
- i = snprintf (buf , sizeof (buf ), "%Le" , 1.0L / 0.0L );
59
- ASSERT_EQ (3 , i );
60
- ASSERT_STREQ ("inf" , buf );
61
-
62
- memset (buf , '\0' , 4 );
63
- i = snprintf (buf , sizeof (buf ), "%g" , 1.0 / 0.0 );
64
- ASSERT_EQ (3 , i );
65
- ASSERT_STREQ ("inf" , buf );
66
-
67
- memset (buf , '\0' , 4 );
68
- i = snprintf (buf , sizeof (buf ), "%Lg" , 1.0L / 0.0L );
69
- ASSERT_EQ (3 , i );
70
- ASSERT_STREQ ("inf" , buf );
71
-
72
- for (i = 4 ; i < 10 ; ++ i )
73
- ASSERT_EQ ('\0' , buf [i ]);
101
+ check_single_double ("%f" , "inf" , 1.0 / 0.0 );
102
+ check_single_long_double ("%Lf" , "inf" , 1.0L / 0.0L );
103
+ check_single_double ("%e" , "inf" , 1.0 / 0.0 );
104
+ check_single_long_double ("%Le" , "inf" , 1.0L / 0.0L );
105
+ check_single_double ("%g" , "inf" , 1.0 / 0.0 );
106
+ check_single_long_double ("%Lg" , "inf" , 1.0L / 0.0L );
74
107
}
75
108
76
109
TEST (snprintf , testUppercaseCConversionSpecifier ) {
77
- char buf [10 ] = {};
78
- int i = snprintf (buf , sizeof (buf ), "%C" , L'a' );
79
-
80
- ASSERT_EQ (1 , i );
81
- ASSERT_STREQ ("a" , buf );
82
-
83
- i = snprintf (buf , sizeof (buf ), "%C" , L'☺' );
84
- ASSERT_EQ (3 , i );
85
- ASSERT_STREQ ("☺" , buf );
110
+ check_single_wint_t ("%C" , "a" , L'a' );
111
+ check_single_wint_t ("%C" , "☺" , L'☺' );
86
112
}
87
113
88
114
// Make sure we don't va_arg the wrong argument size on wide character
@@ -188,74 +214,26 @@ TEST(snprintf, testNConversionSpecifier) {
188
214
}
189
215
190
216
TEST (snprintf , testLongDoubleEConversionSpecifier ) {
191
- char buf [20 ] = {};
192
- int i = snprintf (buf , sizeof (buf ), "%Le" , 1234567.8L );
193
-
194
- ASSERT_EQ (12 , i );
195
- ASSERT_STREQ ("1.234568e+06" , buf );
217
+ check_single_long_double ("%Le" , "1.234568e+06" , 1234567.8L );
196
218
}
197
219
198
220
TEST (snprintf , testLongDoubleRounding ) {
199
221
int previous_rounding = fegetround ();
200
222
ASSERT_EQ (0 , fesetround (FE_DOWNWARD ));
201
223
202
- char buf [20 ];
203
- int i = snprintf (buf , sizeof (buf ), "%.3Lf" , 4.4375L );
204
- ASSERT_EQ (5 , i );
205
- ASSERT_STREQ ("4.437" , buf );
206
-
207
- i = snprintf (buf , sizeof (buf ), "%.3Lf" , -4.4375L );
208
- ASSERT_EQ (6 , i );
209
- ASSERT_STREQ ("-4.438" , buf );
224
+ check_single_long_double ("%.3Lf" , "4.437" , 4.4375L );
225
+ check_single_long_double ("%.3Lf" , "-4.438" , -4.4375L );
210
226
211
227
ASSERT_EQ (0 , fesetround (FE_TOWARDZERO ));
212
228
213
- i = snprintf (buf , sizeof (buf ), "%.3Lf" , -4.4375L );
214
- ASSERT_EQ (6 , i );
215
- ASSERT_STREQ ("-4.437" , buf );
229
+ check_single_long_double ("%.3Lf" , "-4.437" , -4.4375L );
216
230
217
231
ASSERT_EQ (0 , fesetround (previous_rounding ));
218
232
}
219
233
220
- void check_a_conversion_specifier_double (const char * fmt ,
221
- const char * expected_str ,
222
- double value ) {
223
- char buf [30 ] = {0 };
224
- int i = snprintf (buf , sizeof (buf ), fmt , value );
225
-
226
- ASSERT_EQ (strlen (expected_str ), i );
227
- ASSERT_STREQ (expected_str , buf );
228
- }
229
-
230
- void check_a_conversion_specifier_long_double (const char * fmt ,
231
- const char * expected_str ,
232
- long double value ) {
233
- char buf [30 ] = {0 };
234
- int i = snprintf (buf , sizeof (buf ), fmt , value );
235
-
236
- ASSERT_EQ (strlen (expected_str ), i );
237
- ASSERT_STREQ (expected_str , buf );
238
- }
239
-
240
- void check_a_conversion_specifier_long_double_arr_allowed (
241
- const char * fmt , const char * allowed_strs [], long double value ) {
242
- char buf [30 ] = {0 };
243
- int res = snprintf (buf , sizeof (buf ), fmt , value );
244
-
245
- for (size_t i = 0 ; allowed_strs [i ] != NULL ; ++ i )
246
- if (strlen (allowed_strs [i ]) == res && strcmp (allowed_strs [i ], buf ) == 0 )
247
- return ;
248
-
249
- printf ("Failed to find matching str for %`'s, allowed strs:\n" , buf );
250
- for (size_t i = 0 ; allowed_strs [i ] != NULL ; ++ i )
251
- printf ("- %`'s\n" , allowed_strs [i ]);
252
- fflush (stdout );
253
- ASSERT_EQ (false, true);
254
- }
255
-
256
234
void check_a_conversion_specifier_double_prec_1 (const char * expected_str ,
257
235
double value ) {
258
- check_a_conversion_specifier_double ("%.1a" , expected_str , value );
236
+ check_single_double ("%.1a" , expected_str , value );
259
237
}
260
238
261
239
TEST (snprintf , testAConversionSpecifierRounding ) {
@@ -281,23 +259,25 @@ TEST(snprintf, testAConversionSpecifier) {
281
259
check_a_conversion_specifier_double_prec_1 ("0x1.ap+4" , 0x1.98p+4 );
282
260
check_a_conversion_specifier_double_prec_1 ("0x1.ap+4" , 0x1.a8p+4 );
283
261
284
- check_a_conversion_specifier_double ("%#a" , "0x0.p+0" , 0x0.0p0 );
285
- check_a_conversion_specifier_double ("%#A" , "0X0.P+0" , 0x0.0p0 );
286
- check_a_conversion_specifier_long_double ("%#La" , "0x0.p+0" , 0x0.0p0L );
287
- check_a_conversion_specifier_long_double ("%#LA" , "0X0.P+0" , 0x0.0p0L );
288
-
289
- check_a_conversion_specifier_double ("%.2a" , "0x1.00p-1026" , 0xf.fffp-1030 );
262
+ check_single_double ("%#a" , "0x0.p+0" , 0x0.0p0 );
263
+ check_single_double ("%#A" , "0X0.P+0" , 0x0.0p0 );
264
+ check_single_long_double ("%#La" , "0x0.p+0" , 0x0.0p0L );
265
+ check_single_long_double ("%#LA" , "0X0.P+0" , 0x0.0p0L );
290
266
291
- check_a_conversion_specifier_double ("%.1a " , "0x2.0p+0 " , 1.999 );
267
+ check_single_double ("%.2a " , "0x1.00p-1026 " , 0xf.fffp-1030 );
292
268
269
+ check_single_double ("%.1a" , "0x2.0p+0" , 1.999 );
293
270
const char * acceptable_results1 [] = {"0x1.0p+1" , "0x2.0p+0" , NULL };
294
- check_a_conversion_specifier_long_double_arr_allowed (
271
+ check_single_long_double_arr_allowed (
295
272
"%.1La" , acceptable_results1 , 1.999L );
296
273
}
297
274
298
- TEST (snprintf , apostropheFlag ) {
299
- char buf [20 ];
300
- int i = snprintf (buf , sizeof (buf ), "%'d" , 1000000 );
301
- ASSERT_EQ (7 , i );
302
- ASSERT_STREQ ("1000000" , buf );
275
+ TEST (snprintf , testApostropheFlag ) {
276
+ check_single_int ("%'d" , "10000000" , 10000000 );
277
+ }
278
+
279
+ TEST (snprintf , testUppercaseBConversionSpecifier ) {
280
+ check_single_int ("%B" , "0" , 0 );
281
+ check_single_int ("%B" , "10" , 2 );
282
+ check_single_int ("%#B" , "0B10011" , 19 );
303
283
}
0 commit comments